前言

上课的时候看到老师用迭代器来遍历 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. 点的双联通+二分图的判定(poj2942)

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 10804   Acce ...

  2. Java SE series:1. environment configure and Hello world! [We use compiler and packager to create an application!]

    1. cli (command line interface) and gui (graphic user interface) use javahome path, search classpath ...

  3. 解决 Xamarin 拖拽Plain Text 于Layout上时 出现 “The layout could not be loaded:java.lang.System.arraycopy([CI[CII)V” 错误

    右键项目属性

  4. angular 自定义指令 link

    function link(scope, element, attrs) { ... } where: scope is an Angular scope object. element is the ...

  5. mongodb子文档查询

    --子文档分页 -- 测试数据 db.childTests.insert({ "_id" : 1, "item" : "ABC", &quo ...

  6. oracle的函数

    1:nvl函数 nvl函数将一个null值转换为一个实际的值,数据类型可以是日期,数字,字符,数据类型必须匹配,vl能够转换任何数据类型,但是转换的数据类型返回值必须是nvl(expr1,expr2) ...

  7. SqlSever中Index Seek的匹配规则(一)

    我们知道在SqlServer中,索引对查询语句的优化起着巨大的作用,一般来说在执行计划中出现了Index Seek的步骤,我们就认为索引命中了.但是Index Seek中有两个部分是值得我们注意的,我 ...

  8. Entity Framework 无法对没有主键的视图映射实体的解决办法

    我们在使用Entity Framework的时候经常会把数据库中的某一个视图映射为EF的实体,但是如果数据库视图中的列没有包含表的主键列,EF会报出警告说视图没有主键,导致视图映射为实体失败,错误如下 ...

  9. Java应用程序的打包和发布

    Java应用程序的打包和发布 简化Java应用程序的打包和发布 发布Java应用程序时Java提供了一系列打包和发布工具,可以显著的简化发布过程 该文章提供了打包Java code的几种方法,探讨Ja ...

  10. Xml游标

    Mainactivity package com.exmple.xmlstream; import java.util.ArrayList; import java.util.List; import ...