序言
工欲善其事 工欲善其事
自认是两个合作开发人员,每晚直面的事是写标识符和无赖逼了。但是常常觉得他们这两个事没达到两个结合点,总觉得每晚写标识符的天数太少了,都没多少让他们吹的天数了。不知道他们是不是这些难题和困惑呢?
他们未知合作开发人员是最会贪心的微生物!哎!那么难题来了,那怎么北窝天数却是这么少呢?何况是他们太菜了吗?不不不,可不要虽说他们,那会是啥其原因嘞?
标准答案是,当然是你还没看这首诗呗,责任编辑切身感受合作开发人员之伤痛,另一面默默地难忍重新整理了一首诗,现在撷取给他们,希望对他们有所协助。
产品目录
总体自动更新图JSON导出辅助工具HTTP互联网允诺辅助工具数组处置辅助工具子集处置辅助工具文档流处置辅助工具FAT辅助工具JAVA bean 第一类切换辅助工具内存和开闭辅助工具开始上手
总体自动更新图
责任编辑会从图中进行分类促发,如是说相关辅助软件包,并单纯如是说采用。因为责任编辑字数非常有限,所以只当作是两个慢板。具体内容技术细节却是都得他们在写标识符的时候渐渐感受。
JSON 导出辅助工具
json 导出辅助工具在合作开发多常见坚信不必我多说了吧,可以说是合作开发人员整天加进的辅助工具,这也是我将它放在第两个来说的其原因,上面他们来一起看一下,归纳和采用吧,GO! 本栏布季谢的比较多的是 Fastjson,它是穆萨开放源码的这款进行 JSON 导出的辅助工具,用语也是十分单纯。
JSONObject只是一种数据结构,可以理解为JSON格式的数据结构(key-value 结构),可以采用put方法给json第一类添加元素。JSONObject可以很方便的切换成数组,也可以很方便的把其他第一类切换成JSONObject第一类
// 数组转JSONObject第一类JSONObject jsonObject = JSONObject.parseObject(“{“name“:”小明“,”age“:18}”); // JSONObject第一类转数组 String str= jsonObject.toJSONString();JSON 数组转化为 子集类// 定义导出数组 String studentListStr = “[{“name“:”小明“,”age“:18},{“name“:”小牛“,”age“:24}]”; // 导出为 List<Student> List<Student> studentList = JSON.parseArray(studentListStr, Student.class); // 定义导出字符串 String studentMapStr = “{“name“:”小明“,”age“:18}”; // 导出为 Map<String,String> Map<String, String> stringStringMap = JSONObject.parseObject(studentMapStr,new TypeReference<Map<String, String>>(){});fastjson 就如是说到这里,这里只是如是说了单纯的采用,更加详细的用语请参考官方的文档,里面还有更多的用语等着你的哦~~
HTTP 互联网允诺辅助工具
除了 JSON 辅助工具,作为两个优秀的互联网打工人,不学会互联网允诺,怎么能够在这个行业占有一席之地呢?HTTP 互联网允诺辅助工具你值得拥有~~ 根据我的个人意愿,我单纯如是说 httpclient的用语,因为我对这个比较熟悉
响应状态为:HTTP/1.1 200 OK 响应内容长度为:-1 响应内容为:
GET 允诺(有参) /** * 有参的 GET 允诺 */ public static void haveArgsGetHttp() throws IOException, URISyntaxException { // 定义 httpclientCloseableHttpClient httpClient = HttpClientBuilder.create().build();// 创建参数列表 List<NameValuePair> valueParamsList = newArrayList<>(); valueParamsList.add(new BasicNameValuePair(“studentId”,“1”)); // 创建对应允诺 Uri URI uri = newURIBuilder() .setScheme(“http”) .setHost(“localhost”) .setPath(“/getStudentInfo”) .setParameters(valueParamsList) .build();// 根据 Uri 创建 httpGet HttpGet httpGet = new HttpGet(uri); // 定义返回结果 CloseableHttpResponse execute = null; // 发送执行 execute = httpClient.execute(httpGet); HttpEntity entity = execute.getEntity(); System.out.println(“响应状态为:” + execute.getStatusLine()); if(Objects.nonNull(entity)) { System.out.println(“响应内容长度为:” + entity.getContentLength()); System.out.println(“响应内容为:” + EntityUtils.toString(entity)); } // 释放资源 if (httpClient != null) { httpClient.close(); }if (execute != null) { execute.close(); } }POST 允诺(有参数)/** * post 有参数 */ public static void haveArgsPosthttp() throws IOException { // 获得Http客户端(可以理解为:你得先有两个浏览器;注意:实际上HttpClient与浏览器是不一样的) CloseableHttpClient httpClient = HttpClientBuilder.create().build(); // 创建Post允诺HttpPost httpPost =new HttpPost(“http://localhost:12345/posttest”); JSONUtil.Student student = newJSONUtil.Student(); student.setName(“潘晓婷”); student.setAge(18); String jsonString = JSON.toJSONString(student); StringEntity entity =new StringEntity(jsonString, “UTF-8”); // post允诺是将参数放在允诺体里面传过去的;这里将entity放入post允诺体中 httpPost.setEntity(entity); httpPost.setHeader(“Content-Type”, “application/json;charset=utf8”); // 响应模型 CloseableHttpResponse response = httpClient.execute(httpPost); // HttpEntity responseEntity = response.getEntity(); System.out.println(“响应状态为:”+ response.getStatusLine());if (responseEntity != null) { System.out.println(“响应内容长度为:”+ responseEntity.getContentLength()); System.out.println(“响应内容为:” + EntityUtils.toString(responseEntity)); } // 释放资源 if (httpClient != null) { httpClient.close(); } if (response != null) { response.close(); } }啊!这样一步一步总结下来好累啊,看到这里的小伙伴们,点一下手里的小赞。嘿嘿~~ 当然我只是单纯如是说一下 httpClient的采用,具体内容高深的采用方法和配置可以参考其他博主的详细如是说,让他们如是说下两个常见的辅助工具吧。
数组处置辅助工具
数组使他们合作开发中最常见的类型,也是他们最常需要操作的类型了。如果不知道数组的常见辅助工具,那在写标识符的时候简直是场灾难!!!
数组判空,截取数组、切换大小写、分隔数组、比较数组、去掉多余空格、拼接数组、采用正则表达式等等。
StringUtils 给他们提供了非常丰富的选择。他们着重以本类来如是说采用。
导入maven坐标<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency>常见方法如是说数组判空 ⭐⭐⭐(isNotBlank 和 isBlanK)
String str = ” “; // 是否不为空boolean res1 = StringUtils.isNotBlank(str); // 是否为空 boolean res2 = StringUtils.isBlank(str);(isNotEmpty 和 isEmpty)
String str = ” “; // 是否不为空 boolean res1 = StringUtils.isNotEmpty(str); // 是否为空 boolean res2 = StringUtils.isEmpty(str);优先推荐采用 isBlank 和 isNotBlank 方法,因为 它会把空数组也考虑进去。
分隔数组 —— split —— ⭐⭐⭐String str2 = “1,2,3”; String[] split = StringUtils.split(str2); System.out.println(Arrays.toString(split));相较于 String 的 split 方法来说,StringUtils 的 split 方法不会有空指针异常
判断是否纯数字 —— isNumeric —— ⭐⭐给定两个数组,判断它是否为纯数字 可以采用isNumeric方法
String str3 = “1”; booleannumeric = StringUtils.isNumeric(str3); System.out.println(numeric);当然,这个辅助工具类除了上面单纯的三个方法之外们还有其他很多对于他们来说很采用的方法,但是这里就不一一举例了, 有兴趣的小伙伴们可以看源码统计一下
子集相关处置辅助工具
哦吼~~看完了数组的常见辅助工具,重中之重的子集它来了,如果说没数组,他们的程序就无法运行,那么没子集,他们将会是每晚在上工的中度过了,出去后将会自豪的说,老板的车轮胎我也是做了贡献的。
既然子集辅助工具这么重要,那么当然要重点如是说。学会相关辅助工具的采用,真的是能让他们事半功倍的,真的是能让北窝天数大大增加的,不信你看看。
Collections
它是 JAVA 的子集辅助软件包,内部包括了很多他们常见的方法,下图展示了其中一些,方便食用!
在他们日常合作开发工作中,经常会遇到一些子集排序的需求。sort就可以很好的协助他们做好这一点
List<Integer> list = new ArrayList<>(); list.add(2); list.add(1); list.add(3); //升序 Collections.sort(list); System.out.println(list); //降序 Collections.reverse(list); System.out.println(list);结果: [1, 2, 3] [3, 2, 1]
最大值最小值是他们操作子集最常见的方法了吧!!Collections 就有现成的方法协助他们实现
// 最大值最小值 List<Integer> intList = new ArrayList<>(); intList.add(1); intList.add(2); intList.add(3); Integer max = Collections.max(intList); Integer min = Collections.min(intList); System.out.println(“子集元素最大值:”+max); System.out.println(“子集元素最小值:” + min);结果:子集元素最大值:3 子集元素最小值:1
切换线程安全子集—— synchronizedList ——⭐⭐⭐在多线程状态下,普通子集会产生并发难题,比如 ArrayList 并发添加会产生空值情况,这时他们又不想改动他们之前的子集怎么办? 他们单纯的通过Collections的线程安全转化就可以做到了,简单纯单一行标识符就可以做到!是不是方便的很!
List<Integer> synchronizedList = Collections.synchronizedList(intList);当然,Collections还有很多有用和有趣的方法等着他们去探索,只是只是作为了两个抛转引玉的效果,就不过多的赘述了。
CollectionUtils
我最常见的便是 CollecionUtils,它是 apache开放源码的辅助软件包。它的功能可以说是十分强大的,不信你可以往下看看,反正你能想到的子集操作基本上它都有。
他们最常见的子集方法,没之一,必须掌握它!!
List<String> stringList =new ArrayList<>(); booleannotEmpty = CollectionUtils.isNotEmpty(stringList); System.out.println(“子集不是空的吗?”+ notEmpty);子集不是空的吗?false
交集/并集/补集/差集——⭐⭐⭐在合作开发中,经常需要将多子集进行交并补等的数学操作,不会却是傻傻的子集写循环处置吧!那样还能有北窝的天数吗?上面是大大提升效率的辅助工具!!!
List<Integer> list1 = new ArrayList<>(); list1.add(1); list1.add(2); list1.add(3); List<Integer> list2 = new ArrayList<>(); list2.add(3); list2.add(4); // 获取并集 Collection<Integer> union = CollectionUtils.union(list1, list2); System.out.println(union); // Collection<Integer> intersection = CollectionUtils.intersection(list1, list2); System.out.println(intersection);Collection<Integer> disjunctionList = CollectionUtils.disjunction(list1, list2); System.out.println(disjunctionList); Collection<Integer> subtract = CollectionUtils.subtract(list1, list2); System.out.println(subtract);两子集并集: [1, 2, 3, 4]
两子集交集: [3]
两子集交集的补集:[1, 2, 4]
两子集差集: [1, 2]
判断两子集是否相等——isEqualCollection——⭐⭐⭐// 判断两子集是否相等 List<Integer> list3 = newArrayList<>(); list1.add(3); list1.add(4); List<Integer> list4 = new ArrayList<>(); list2.add(3); list2.add(4); boolean equalCollection = CollectionUtils.isEqualCollection(list3, list4); System.out.println(“两子集相等吗?:” + equalCollection);两子集相等吗?:true
Lists
最后在子集的辅助工具类中再补充两个 google官方的java包,里面有很多他们想不到的超级方便的小辅助工具,既然是说子集,他们说一下它里面的Lists 类,也是超级好用的!
坚信他们在合作开发中,都有过初始化子集的需要吧!那么他们一般都是 新建两个 ArrayList 然后两个两个 add 进去,现在告诉他们,不必这么麻烦,两个方法新建带初始化全搞定,真香警告!!
// 快速初始化子集ArrayList<Integer> integers1 = Lists.newArrayList(1, 2, 3); System.out.println(integers1);[1, 2, 3]
子集分页——partition——⭐⭐⭐有时候他们想将他们的大子集分散成为一些小子集,他们又不想手动操作怎么办?这些痛点肯定已经有人协助他们想好了!!来来来,如是说一下!!
// 数组分页 ArrayList<Integer> list7 = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); List<List<Integer>> partition = Lists.partition(list7, 5); System.out.println(partition);[ [1, 2, 3, 4, 5], [6, 7, 8, 9, 10] ]
如是说完了 子集相关的操作类,上面他们也要如是说一下文档流相关操作,这个操作在合作开发中也是经常加进的。
文档流处置辅助工具
坚信他们在工作已经厌烦了,经常写** IO 流相关的类了吧。经常单纯的读取和写入两个文档,他们需要大费周章的去定义一些 InputStream 和OutputStream **等,觉得有一种杀鸡用牛刀的错觉。 如是说两个文档操作辅助工具类,省去大量操作和关闭行为,超级好用,平常我可是经常见的。
最最常见的操作,怎么样很单纯吧,就只用一行标识符,秒杀!
// 将 test 写入 test.txt 文档 FileUtils.writeByteArrayToFile(new File(“C:\Users\test.txt”),“test”.getBytes());从文档读取信息——readFileToByteArray——⭐⭐⭐知道了怎么往文档里写东西,他的好兄弟读取他们也得知道啊!
// 读取 test.txt 文档 byte[] bytes = FileUtils.readFileToByteArray(new File(“D:\Users\test.txt”)); System.out.println(“读取到的文本为:” + new String(bytes));读取到的文本为:test
API 很多,我也不能一一为他们如是说,深入的了解还需要他们去,熟练地运用起来,并且是不是的去看看官方的文档,查漏补缺,坚信你也可以见识到很多让你叹为观止的方法。
FAT辅助工具类
平常他们经常会遇到比如对用户的密码进行加密 (MD5) ,校验接口的签名 (sha256) 加密等等 加进加密的场景虽然不是很多,但是有这样的辅助工具何乐而不为呢?
因为常见的加密方法并不多,这里如是说两个方法给他们,想知道其他更多用语的伙伴们,去他们探索吧
MD5加密后的结果:
ef1fedf5d32ead6b7aaf687de4ed1b71sha256加密后:
a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e3JAVA bean 第一类切换辅助工具
说到这里,他们来说一下第一类转化的辅助工具,在合作开发些规范,比如DTO、DO、VO等等,之间,如果他们需要切换,单纯的他们要两个两个的 set 值,真是一项苦逼的活。
BeanUtils
java bean第一类的相关转化,我在这里如是说两个 ,两个 是他们都非常熟悉的 BeanUtils,还有两个是我平常在合作开发中经常采用的 MapStruct 和 BeanUtils 最常见的莫过于第一类的的拷贝了 。 不过直面需要深拷贝的第一类他们要注意了,这里并不推荐他们采用此辅助工具去实现
Student student =new Student(); student.setName(“小明”); student.setAge(18); Student newStudent = newStudent(); BeanUtils.copyProperties(student,newStudent); System.out.println(newStudent);Student(name=小明, age=18)
MapStruct
上面他们重点说一下 MapStruct 这个转化,BeanUtils是两个大老粗,只能同属性映射,或者在属性相同的情况下,允许被映射的第一类属性少。
但当遇到被映射的属性数据类型被修改或者被映射的字段名被修改,则会导致映射失败。而 mapstruct 是两个巧媳妇儿了。
她心思细腻,把他们可能会遇到的情况都给考虑到了(要是我也能找两个这样的媳妇儿该多好,内心笑出了猪声)
首先啥都不必想上来他们先把该导的包导进去<dependency> <groupId>org.mapstruct</groupId> <!– jdk8以下就采用mapstruct –> <artifactId>mapstruct-jdk8</artifactId> <version>1.2.0.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.2.0.Final</version> </dependency>用一下第一类之间字段完全相同第一步:定义好他们的基础类
@Data @AllArgsConstructor @NoArgsConstructorpublic class Student{private String name; private Integer age ; } @Data @AllArgsConstructor @NoArgsConstructor public class Teacher{ private String name; private Integer age ; }第二步:接下来定义两个接口,但是注意不需要实现,他就呢能够帮他们转化很神奇的
@Mapper public interface UserCovertToTeacher { UserCovertToTeacher INSTANCE = Mappers.getMapper(UserCovertToTeacher.class); Teacher toCovert(Student student); }最后一步:在标识符中调用,聪明的小伙伴看上面标识符,一下就明白了,是这么单纯
Student student =new Student(); student.setName(“小明”); student.setAge(18); Teacher teacher = UserCovertToTeacher.INSTANCE.toCovert(student); System.out.println(teacher);Teacher(name=小明, age=18)
第一类之间字段存在不相同情况他们如是说了完全两个类字段相同的情况,那么,更加令他们头疼的 有多个字段名字不同但是有对应关系应该怎么搞呢?
他们进阶如是说一下,如何处置这种参数名不同的对应关系 目前假设他们新定义两个微信类,他们的学生要注册到微信上,他们就要将学生第一类转化为微信第一类
@Data @AllArgsConstructor @NoArgsConstructor static class WeiXin{ private String username; private Integer age ; }但是他们发现和他们上面的学生类,的名字参数名不同,怎么对应过去的? 标准答案是在对方法上配置
@Mapper public interface UserCovertToWeinxin { UserCovertToWeinxin INSTANCE = Mappers.getMapper(UserCovertToWeinxin.class); // 配置字段映射规则 @Mapping(source = “name”,target = “username”) BeanUtilTest.WeiXin toCovert(BeanUtilTest.Student student); }Student student = new Student(); student.setName(“小明”); student.setAge(18); WeiXin weiXin = UserCovertToWeinxin.INSTANCE.toCovert(student); System.out.println(weiXin);WeiXin(username=小明, age=18)
这么单纯的两个小例子可包含不了 MapStruct这么强大的功能,不管是日期格式化、却是表达式导出、却是深拷贝,都能一一搞定,只是限于本首诗,无法跟他们说了。想想都很伤心呢! 但是却是那句话,抛砖引玉么!剩下的就交给聪明的小伙伴们了!
内存和开闭器辅助工具
最后一小节,我给他们带来我的珍藏,压箱底的东西要拿出来了,他们还不快快点赞收藏,记好,错过了,可就没下家店了。
我也是在 guava中发现了很多好用的辅助工具的 首先如是说内存辅助工具,合作开发中,他们常见的内存内存,也就常常是定义两个 Map 去存放,但是单纯的 Map 只能存和取,确无法做到,内存过期、内存淘汰,和相关通知等等复杂操作。
他们有必要学习掌握一种辅助工具,能够 Cover 上面所有情况的内存辅助工具,有需求就有辅助工具类,永远记住。!!!,Cache登场了,却是老规矩,先看看它怎么用吧。
Cache
定义两个单纯定时过期的内存
Cache<String, String> cache = CacheBuilder.newBuilder() .expireAfterWrite(10, TimeUnit.SECONDS) .build(); // 放入内存 cache.put(“小明”,“活着”); Thread.sleep(10000); // 从内存拿取值 System.out.println(cache.getIfPresent(“小明”));null
看到没,结果显而易见,超过了内存天数,就会他们释放。嘿嘿。
定义两个内存符合以下限制:
限制访问并发设置初始化容量限制内存数量上限Cache<String, String> cache = CacheBuilder.newBuilder()、 // 最大容量,超过按照 LRU 淘汰.maximumSize(100) // 初始容量 .initialCapacity(10) // 并发等级 10 .concurrencyLevel(10) .expireAfterWrite(10, TimeUnit.SECONDS) .build();两个小例子,他们看明白了没,真正的干货,还不赶紧用起来。
除了这个,两个开闭器也是常常需要的,他们总不能自记去写两个开闭器吧,需要考虑的太多,性能还不行哎!那就用接下来如是说的这个辅助工具
RateLimiter
开闭器他们在并发场景下经常会遇到,最单纯的实现开闭是令牌桶算法,原理很单纯,但是具体内容实现是很复杂的,RateLimiter协助他们解决这一点,只需要调用单纯的API 就能实现并发开闭
定义开闭器,每1秒钟通过 1 个允诺
RateLimiter rateLimiter = RateLimiter.create(1,1,TimeUnit.SECONDS);new Thread(()->{ System.out.println(+ rateLimiter.tryAcquire()); }).start();new Thread(()->{ System.out.println(+ rateLimiter.tryAcquire()); }).start();怎么样,是不是只能有两个通过,单纯例子说明难题。 具体内容用语还得他们在实际合作开发中具体内容感受,本栏在这里就不多BB了!!留着天数他们赶快去练习吧。争取成为两个 API 调用高手。
修炼完成
经过上面这么多的讲解、案例和对知识的思考,坚信他们已经初步掌握了线程池的使用方法和技术细节,以及对原理运行流程的掌握, 如果你觉得责任编辑对你有一定的启发,引起了你的思考。 点赞、转发、收藏,下次你就能很快的找到我喽!