我们都知道JDK现在使用的比较普遍的还是 JDK8,也有人说是 JDK11 但是了不起解除的项目,目前还没有直接升级到 JDK11 的,毕竟语法有一些改变,而且还有语法糖的存在,但是 JDK8 已经算是普及了,就算是培训机构,也早就从 JDK7 已经升级教学到 JDK8了,今天了不起也就来说说我们使用 JDK8 中的各种小玩意,可以让自己的开发效率加倍。
JDK8中的快捷小技巧
我们直接从问题然后来区分这个 JDK7 和 JDK8 中完成相同的功能所实现的方式有什么不同,来看看为什么现在都比较喜欢使用 JDK8.
1.筛选班级里面年龄大于15岁的人 2.两个班级人员比计较,去掉某一个班中年龄相同的人。
我们有两个班级的人,分别是两个 List,也就是1班和二班
代码语言:javascript复制List<Student> studentClassTwo = new ArrayList<>();
List<Student> studentClassOne = new ArrayList<>();
两个班级人员都有这些人:
代码语言:javascript复制一班人员[{"age":13,"id":"5301a4c6b57a420eadd71f25eb2931c1","name":"张三"},{"age":14,"id":"6390153a42ed4c4fa00c4d4860ef5aeb","name":"李四"},{"age":15,"id":"d392e1921f794f9e8b6c90594901ef55","name":"王五"},{"age":16,"id":"9416726db1744347be041641ba06cc8b","name":"赵六"}]
二班人员[{"age":12,"id":"6980c4b19a3d45b4b9729a967953b923","name":"张华"},{"age":18,"id":"a6b151560ff54b688dbfff0840f37221","name":"白条"},{"age":15,"id":"d2b09908b2c8482c9b3054fb17388a47","name":"刘能"},{"age":16,"id":"0319b35334bb45d488e332f90a6505af","name":"赵刚"}]
这是了不起准备的数据,接下来我们分别来看看上面准备的三个问题,每个问题,使用 JDK7 和 JDK8 的实现方式来安排一下。
问题一:筛选班级里面年龄大于15岁的人
我们如果要筛选班级里面大于15岁的人,那么肯定离不开循环,然后我们去找一下每个班级里面,年龄大于15对的人。
JDK7:
代码语言:javascript复制 List<Student> endStudent = new ArrayList<>();
for (Student stud:studentClassOne) {
if (stud.getAge() >15){
endStudent.add(stud);
}
}
System.out.println("年龄符合大于15岁的学生" JSON.toJSONString(endStudent));
结果:
代码语言:javascript复制年龄符合大于15岁的学生[{"age":16,"id":"b260b0ce729f45158a6071bcef6218fc","name":"赵六"}]
我们从1班里面筛选出了一个赵六,他是大于15岁的人,功能实现,已经OK了,而JDK8应该怎么实现?
代码语言:javascript复制 List<Student> endStudent = studentClassOne.stream().filter(stud -> stud.getAge() > 15).collect(Collectors.toList());
System.out.println("年龄符合大于15岁的学生" JSON.toJSONString(endStudent));
同样的结果,
代码语言:javascript复制年龄符合大于15岁的学生[{"age":16,"id":"b260b0ce729f45158a6071bcef6218fc","name":"赵六"}]
但是,我们直接使用 JDK8 所提供的 Stream 流就完成了这个操作,是不是感觉在开发上,直接省去了不少的代码。
那么这个 Stream 应该怎么去理解?
Stream的特性:
代码语言:javascript复制1.stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。
2.stream不会改变数据源,通常情况下会产生一个新的集合或一个值。
3.stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。
Stream的特点
代码语言:javascript复制1.代码简洁:函数编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环。
2.多核友好:Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下方法。
3.Stream不存储数据
4.Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。
5.Stream是惰性求值的(延迟执行)
而这个 filter,实际上就是用于通过设置的条件过滤出元素,filter中也是可以有组合条件,而不单单是单一条件,至于想写是多少条件,那就得看你的需求了,话不多说,我们来继续看第二个问题。
问题二:两个班级人员比计较,去掉某一个班中年龄相同的人。
这个问题来了,我们是不是需要去循环对比,然后通过比较每个学生的年龄,然后去掉年龄相同的人。
JDK7的实现方式:
我们看一下两个班的人员,2班中年龄和1班中重复的,有刘能和赵刚,那么我们在实现之后,二班中的人,是不是就只剩下了张华和白条了。
代码语言:javascript复制 for (int i = 0; i < studentClassOne.size(); i ) {
for (int j = 0; j < studentClassTwo.size(); j ) {
if (studentClassOne.get(i).getAge() == studentClassTwo.get(j).getAge()){
studentClassTwo.remove(j);
}
}
}
System.out.println("符合条件的数据" JSON.toJSONString(studentClassTwo));
输出结果:
代码语言:javascript复制符合条件的数据[{"age":12,"id":"af1220fc11834adf86b2266e67c21556","name":"张华"},{"age":18,"id":"b308432f79d84d0695bf871cebc77c54","name":"白条"}]
我们从2班中,把只要和1班里面年龄相同的学生都移除了,JDk7实现了,那么JDK8怎么实现呢?
代码语言:javascript复制 studentClassTwo.removeIf(studTwo->studentClassOne.stream().anyMatch(studOne->studTwo.getAge() == studOne.getAge()));
System.out.println("符合条件的数据" JSON.toJSONString(studentClassTwo));
输出看结果:
代码语言:javascript复制符合条件的数据[{"age":12,"id":"5a5dd02bc8354ef48b2045cb2cf84414","name":"张华"},{"age":18,"id":"933cc8ce944946579b00fd6740409215","name":"白条"}]
结果一样,但是代码量很明显,少了不少,但是可读性就没有那么强了,如果是一个对 JDK8 没有那么熟练的人来看,甚至都不知道逆向实现什么功能。
这里,我们再来看看这个 Stream 提供的一下关键的操作。
- filter 我们已经说过了,不再赘述
- distinct 返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流。
- limit 会返回一个不超过给定长度的流。
- skip 返回一个扔掉了前n个元素的流。
- map 接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一个新版本”而不是去“修改”)。
- flatMap 使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流。
我们来分别演示一下后面的这几个关键字的用法:
distinct
代码语言:javascript复制 List<Integer> integerList = new ArrayList<>();
integerList.add(1);
integerList.add(1);
integerList.add(2);
integerList.add(3);
integerList.add(4);
List<Integer> collect = integerList.stream().distinct().collect(Collectors.toList());
System.out.println("符合条件的数据" JSON.toJSONString(collect));
代码语言:javascript复制符合条件的数据[1,2,3,4]
skip
代码语言:javascript复制 List<Integer> collect = integerList.stream().skip(2).collect(Collectors.toList());
System.out.println("符合条件的数据" JSON.toJSONString(collect));
输出结果:
代码语言:javascript复制符合条件的数据[2,3,4]
limit
代码语言:javascript复制 List<Integer> collect = integerList.stream().limit(2).collect(Collectors.toList());
System.out.println("符合条件的数据" JSON.toJSONString(collect));
输出结果:
代码语言:javascript复制符合条件的数据[1,1]
map:
代码语言:javascript复制List<Integer> collect = studentClassOne.stream().map(Student::getAge).collect(Collectors.toList());
System.out.println("符合条件的数据" JSON.toJSONString(collect));
输出结果:
代码语言:javascript复制符合条件的数据[13,14,15,16]
flatMap;
代码语言:javascript复制 List<String> stringList = Arrays.asList("hello", "world");
List<String> collect = stringList.stream()
.map(str -> str.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
System.out.println("符合条件的数据" JSON.toJSONString(collect));
执行结果:
代码语言:javascript复制符合条件的数据["h","e","l","o","w","r","d"]
其实关于 JDK8 的使用,很多都是需要在日积月累的情况下才能慢慢的熟练,如果说一时间让你去学习,那么有很多方法,你不用了之后,慢慢的还是会遗忘。
所以关于 JDK8 的小技巧你学会了么?