前言

上课的时候看到老师用迭代器来遍历 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方法。

Java 使用 Stream API 筛选 List的更多相关文章

  1. Java 8 Stream API

    Java 8 Stream API JDK8 中有两大最为重要的改变.第一个是 Lambda 式:另外 Stream API(java.util.stream.*) Stream 是 JDK8 中处理 ...

  2. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...

  3. Java 8 Stream API Example Tutorial

    Stream API Overview Before we look into Java 8 Stream API Examples, let’s see why it was required. S ...

  4. Java 8 Stream API具体解释

    Java 8 Stream API具体解释 一.Stream API介绍 Java 8引入了全新的Stream API,此Stream与Java I/O包里的InputStream和OutputStr ...

  5. Java 8 Stream Api 中的 peek 操作

    1. 前言 我在Java8 Stream API 详细使用指南[1] 中讲述了 [Java 8 Stream API]( "Java 8 Stream API") 中 map 操作 ...

  6. Spring WebFlux 学习笔记 - (一) 前传:学习Java 8 Stream Api (2) - Stream的中间操作

    Stream API Java8中有两大最为重要的改变:第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*). Stream 是 Java8 中处 ...

  7. Spring WebFlux 学习笔记 - (一) 前传:学习Java 8 Stream Api (1) - 创建 Stream

    影子 在学习Spring WebFlux之前,我们先来了解JDK的Stream,虽然他们之间没有直接的关系,有趣的是 Spring Web Flux 基于 Reactive Stream,他们中都带了 ...

  8. Java 8 Stream API 详解

    Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (b ...

  9. Java 8 Stream API 引入和使用

    引入流 流是什么 流是Java API的新成员,它允许你以声明性的方式处理数据集合.可以看成遍历数据集的高级迭代.流可以透明地并行处理,无需编写多线程代码.我们先简单看一下使用流的好处.下面两段代码都 ...

随机推荐

  1. Python条件循环判断

    1.条件判断语句 Python中条件选择语句的关键字为:if .elif .else这三个.其基本形式如下: 1 2 3 4 5 6 7 8 9 age_of_cc = 27   age = int( ...

  2. [转]MySQL数据库引擎介绍、区别、创建和性能测试的深入分析

    本篇文章是对MySQL数据库引擎介绍.区别.创建和性能测试进行了详细的分析介绍,需要的朋友参考下   数据库引擎介绍 MySQL数据库引擎取决于MySQL在安装的时候是如何被编译的.要添加一个新的引擎 ...

  3. [转]Eclipse Java注释模板设置详解

    原文链接:http://blog.csdn.net/ahhsxy/archive/2009/09/11/4542682.aspx 设置注释模板的入口: Window->Preference-&g ...

  4. [转]-Dmaven.multiModuleProjectDirectory system propery is not set. 解决方案 适用于myeclipes 和 eclipes

    eclipse中使用maven插件的时候,运行run as maven build的时候报错 -Dmaven.multiModuleProjectDirectory system propery is ...

  5. JAVA面试题之实现字符串的倒序输出

    package shb.java.demo; public class MyTest { public static void main(String[] args) { String string ...

  6. C# 文件读取(二)

    将我的电脑中的文件夹信息显示到TreeView控件上. 方法很多种,下面这种方法添加了我的文档. public partial class Form1 : Form { public Form1() ...

  7. 【python】标准库的大致认识

    正如那句 Python 社区中很有名的话所说的:“battery included”,Python 的一大好处在于它有一套很有用的标准库(standard library).标准库是随着 Python ...

  8. yii2细节设置

    1.设置默认的跳转登陆页面.默认的登陆成功页 在项目的(backend/frontend的config中的main.php中的user组件中),添加loginUrl=>'admin/login' ...

  9. linux终端快捷键

    tab 补全 ctrl+k 删除此处到末尾所有内容 ctrl+u 删除此处到开始所有内容 ctrl+a 将光标移至开始处 cttl+e 将光标移至结尾 ctrl+l 清屏 ctrl+c 删除整行或停止 ...

  10. 161114、websocket实现心跳重连

    心跳重连缘由 在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开, 而浏览器不会执行websocket 的 onclos ...