Java8-Stream流操作List去重distinct、和指定字段去重(完整实例讲解)_stream distinct去重指定字段-程序员宅基地

技术标签: Java8+  list去重  指定字段去重  java8  stream  distinct  

使用Java8的Stream的distinct方法去重,我们的对象需要实现hashcode()和equals()方法。

把学生类修改后如下:

public class Student {
    private Long id;
    private String name;
    private int age;
    private Double height;

    public Student(Long id, String name, int age, Double height) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(id, student.id) &&
                Objects.equals(name, student.name) &&
                Objects.equals(height, student.height);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age, height);
    }
}

测试例子:

import com.top.test.dto.Student;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class ListStreamDistinctTest {
    public static void main(String[] args) {
        // 一个集合中放入4个学生对象
        List<Student> list = new ArrayList<>();
        list.add(new Student(10002L, "ZhangSan", 18, 175.2));
        list.add(new Student(10001L, "LiSi", 19, 175.2));
        list.add(new Student(10004L, "Peter", 19, 170.8));
        list.add(new Student(10004L, "Peter", 19, 170.8));

        // 按整个个对象去重
        System.out.println("整个对象去重:");
        list.stream().distinct()
                .forEach(System.out::println);

        // 指定某个字段去重
        System.out.println("指定age属性去重(方法一):");
        list.stream().filter(distinctByKey1(s -> s.getAge()))
                .forEach(System.out::println);

        // 方法二(用循环)
        System.out.println("指定age属性去重(方法二):");
        TreeSet<Student> students = new TreeSet<>(Comparator.comparing(s -> s.getAge()));
        for (Student student : list) {
            students.add(student);
        }
        new ArrayList<>(students)
                .forEach(System.out::println);

        // 方法三:(是方法二的变形),此方法来源于:https://blog.csdn.net/qq_28988969/article/details/81119587
        System.out.println("指定age属性去重(方法三):");
        list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(s -> s.getAge()))), ArrayList::new))
                .forEach(System.out::println);


    }

    // 次方法来源于:https://blog.csdn.net/haiyoung/article/details/80934467
    static <T> Predicate<T> distinctByKey1(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}

执行结果:

整个对象去重:
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}
Student{id=10004, name='Peter', age=19, height=170.8}
指定age属性去重(方法一):
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}
指定age属性去重(方法二):
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}
指定age属性去重(方法三):
Student{id=10002, name='ZhangSan', age=18, height=175.2}
Student{id=10001, name='LiSi', age=19, height=175.2}

Lambda表达式和函数式接口看不懂的,可以参考之前的文章:
Java8 Lambda表达式 和 函数式编程 原理详解



沪漂程序员。 坚持写博客,如果觉得还可以的话,给个小星星哦,你的支持就是我创作的动力。

个人微信公众号:“Java尖子生”,阅读更多干货。
关注公众号,领取学习、面试资料。加技术讨论群。


阅读更多我的相关内容
Java8 Lambda表达式 和 函数式编程 原理详解
Java8方法引用,示例讲解
Java8-默认方法和默认静态方法
Java8-Stream流操作List排序(完整实例讲解)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Kurry4ever_/article/details/109638367

智能推荐

每天一点面试题(8) ------------diff算法详解_安卓面试题 diff算法有哪些-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏15次。diff算法的作用计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面。传统diff算法通过循环递归对节点进行依次对比,算法复杂度达到 O(n^3) ,n是树的节点数,这个有多可怕呢?——如果要展示1000个节点,得执行上亿次比较。。即便是CPU快能执行30亿条命令,也很难在一秒内计算出差异。React的diff算法(1)什么是调和?将..._安卓面试题 diff算法有哪些

vagrant up default: Warning: Connection timeout. Retrying_cmd中vagrant up超时-程序员宅基地

文章浏览阅读2.6k次。在ubutun14 系统中安装vagrant执行vagrant up时会出现:==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 de_cmd中vagrant up超时

Python实现图(Graph)及其算法(BFS)_python 图算法-程序员宅基地

文章浏览阅读1w次,点赞8次,收藏40次。注:参考书籍《Python数据结构与算法》1.图的抽象数据类型定义Graph()新建一个空图;addVertex(vert)向图中添加一个顶点(vert)实例;addEdge(fromVert,toVert)向图中添加一条有向边,用于连接顶点fromVert,toVertaddEdge(fromVert,toVert,weight)向图中添加一条带权重(weight)的有向边getVertex(vertKey)在图中找到名为vertKey的顶点getVertices()以列表形_python 图算法

销售管理系统 JavaGUI Swing框架实现版-程序员宅基地

文章浏览阅读1.1w次,点赞5次,收藏80次。销售管理系统 JavaGUI Swing框架实现版_销售管理系统

SICP 2.59 集合的合并union_set_set thinker-程序员宅基地

文章浏览阅读372次。现在有两个集合set1 和 set2, 需要将这两个集合合并成一个集合。 思路很简单: 顺序查找set1中的元素set2是否包含,是,则找下一个,否,加入到set2。 最后返回set2scheme 实现:(define (union_set set1 set2) (if (null? set1) set2 (union_set (cdr set1) (a_set thinker

Android 利用属性动画结合贝塞尔曲线方程编写好看的动画._android 贝塞尔曲线融合动画-程序员宅基地

文章浏览阅读5k次。研究一下贝塞尔曲线./** * 贝塞尔方程 */ private class BeizerEvaluator implements TypeEvaluator { private PointF point1; private PointF point2; private PointF pointF;_android 贝塞尔曲线融合动画

随便推点

AXI总线详解-不同类型的DMA_dma cdma-程序员宅基地

文章浏览阅读1k次。不同类型的DMAGPIOPL general purpose AXIGP AXI utlilizing PS DMACHigh performance w/DMAACP w/DMA几种DMA的总结​ZYNQ中不同应用类型的DMA  几个常用的 AXI 接口 IP 的功能(上面已经提到):  AXI-DMA:实现从 PS 内存到 PL 高速传输高速通道 AXI-HP<---->AXI-Stream 的转换  AXI-FIFO-MM2S:实现从 PS 内存到._dma cdma

Java生成二维码分享海报_java生成小程序二维码海报-程序员宅基地

文章浏览阅读938次。声明:本文转载自http://www.chinacion.cn/article/7931.html,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。这一篇文章我们就用 Java 来生成一下仿金山词霸的海报。As long as you can still grab a breath, you fight. 只要一息尚存,就不得不战。有那么一段时..._java生成小程序二维码海报

人工神经元网络基本构成,人工神经网络主要有_人工神经元的结构以及各部分功能-程序员宅基地

文章浏览阅读870次。人工神经网络(ArtificialNeuralNetwork,即ANN)是从信息处理角度对人脑神经元网络进行抽象,是20世纪80年代以来人工智能领域兴起的研究热点,其本质是一种运算模型,由大量的节点(或称神经元)之间相互联接构成,在模式识别、智能机器人、自动控制、生物、医学、经济等领域已成功地解决了许多现代计算机难以解决的实际问题,表现出了良好的智能特性。_人工神经元的结构以及各部分功能

HTML5+CSS3实现的小风车-转动的童年_h5 css写风车转动-程序员宅基地

文章浏览阅读2.3k次。#windmill{ width:160px; height:160px; position:relative; -moz-transition:-moz-transform 2s ease-in-out; -webkit-transition:-webkit-transform 2s ease-in-out; -moz-transform:rotate(0deg); -webki_h5 css写风车转动

如何判断windows动态链接库是32还是64位_win32动态链接库有64位版本吗-程序员宅基地

文章浏览阅读3.9k次。如何判断windows动态链接库是32还是64位从 http://www.cnblogs.com/conorpai/p/6393120.html 转载而来如果安装过Visual Studio的话,直接打开一个VS提供的控制台窗口,比如VS2012 x64 Native Tools Command Prompt.用下面的命令查看程序的头部信息:“dumpbin /_win32动态链接库有64位版本吗

华为android贡献度,从EMUI的6次里程碑事件,看华为对安卓生态的贡献-程序员宅基地

文章浏览阅读2k次。原标题:从EMUI的6次里程碑事件,看华为对安卓生态的贡献从华为进入手机领域开始至今,EMUI的发展共经历了5次较大的里程碑事件。由于安卓的开源属性,因此,每一次关键问题的解决和核心难题的攻克都是对安卓生态发展的一次贡献。 EMUI5.0:天生一,一生快用安卓的机友都深有体会,安卓系统最大的顽疾就是用几个月,系统就会变得异常卡顿。针对该问题,华为手机在EMUI5.0的时候,推出了“天生一,一生快”..._华为对安卓的贡献

推荐文章

热门文章

相关标签