Java 使用 Stream API 筛选 List
2016-04-16 12:24
721 查看
前言
上课的时候看到老师用迭代器来遍历 List 中的元素的时候,我的内心是极其嫌弃的,这种迭代方法不能直接访问当前的元素,而且写起来也麻烦。于是上网查了查 Java 有没有类似于 Linq 的东西,虽然发现了一个 JLinq 但是抱着学习的心态,还是没有用这个东西。看了看 Intellji 的自动补全然后想出了下面的代码。题目
删除 List 中信息重复的学生解法一
LinkedList<T3.Student> repo3 = new T3.StudentTest().getRepo(); repo3.removeIf(s->repo3.indexOf(s)!=repo3.lastIndexOf(s));
这个方法看起来是没有很大的问题的,但是如果问题稍微变了一下,这就没用了。
题目 update
删除 List 中信息部分重复的学生,也就是只要姓名、年龄相同的学生就认定为信息重复,即使学号不同。解法二
上面的解法一到了这个问题就失效了,对于这个问题我只能想到用下面的代码来解决for (int i = 0; i < repo3.size(); i++) { T3.Student stu = repo3.get(i);//Lambda 表达式不允许我用没被引用的变量,所以就把这句单独提了出来 repo3.removeIf(s->s.equals(stu));//根据题意定义的 equals 方法 }
增加了一个
for循环,其余的基本没变,但是代码的简洁程度相较于使用迭代器得到了大幅度提高。
踩到的坑
0.为毛不用foreach
或者forEach
循环?
foreach不能适应动态变化的集合,因为我在动作中删除了元素。
forEach虽然是一个内部循环,有并行计算的优势,但是还是由于上面的原因不能使用。
1.Stream 接口的操作不会对原有的数据产生影响。
repo3.removeAll(repo3.stream() .filter( s -> repo3.stream().filter(stu -> stu.equals(s)).count() != 0) .collect(Collectors.toList()));
本来我是想用这种方法拿到所有重复的元素,然而事实上是不行的,因为Stream 接口的操作不会对原有的数据产生影响。导致第二个
filter会把所有元素重新扫描一遍,所以需要改成下面的代码:
repo3.removeIf ( s -> repo3 .subList(repo3.indexOf(s),repo3.size()) .stream() .filter(stu -> stu.equals(s)) .count() != 0 );
看起来好像比解法二复杂了许多但是在效率上有很大的进步,
Stream API是并行化的,比外部循环不知道要高到哪里去了,然而这里还存在一个问题,就是在
subList中获得对当前元素的索引的速度可能会拖慢效率,然而,在这道题目的测试用例当中学号起到了索引的作用,然后这里的效率可以大幅度提升。
总结
一开始准备用Stream API我是拒绝的,我看到它是以方法的形式出现的,我还以为会出现类型转换,后来发现这是 Java 缺少
extend methods才出现的东西。然后这个东西实现了跟 Linq 差不多的功能,配合 Lambda 表达式很好用。
那么下面给出最终的版本:
repo3.removeIf ( s -> repo3 .stream() .filter(stu -> stu.equals(s)) .count() != 0 );
这里之所以不需要把 list 截断可能是因为
removeif也是一个
stream方法。
相关文章推荐
- Struts中错误: No result defined for action
- Mac下Maven的安装和配置
- spring 监听器 IntrospectorCleanupListener简介
- MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合
- Java学习-10天
- Java 线程池原理解析(一)
- JAVA修改组件
- spring mvc中的@PathVariable
- eclipse aidl.exe error while creating directories
- 一个Java音乐播放器
- 位运算符详细总结
- 一个求迷宫入口到出口最近距离的程序 JAVA版本
- Struts2 入门学习笔记(四)——输入校验
- JavaWeb系列之八(Cookie&Session)
- Spring中的AOP理解
- java.lang.IllegalStateException: This Activity already has an action bar supplied by the window deco
- Java提高篇(三三)-----Map总结
- Java项目源码学习笔记(一):IdentityCache
- 20145231《Java程序设计》第二次实验报告
- 一个随时间不断变化的值确认其变化范围的方法