Java通过Lambda表达式根据指定字段去除重复数据(集合去重)

简介: Java通过Lambda表达式根据指定字段去除重复数据(集合去重)

这里博主给大家封装好了一个工具类,里面有两个方法。

  • 方法一:可以根据指定字段去除重复数据。
  • 方法二:可以获取到重复的数据。

大家在使用过程中直接拷贝下方代码在要去重的类中调用即可。

package com.jzmy.specialist.entity.util;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
/**
 * 操作去重工具类
 * @author mengzhichao
 * @create 2022-11-02-15:15
 */
public class DeduplicationUtil {
    /**
     * 自定义函数去重(采用 Predicate函数式判断,采用 Function获取比较key)
     * 内部维护一个 ConcurrentHashMap,并采用 putIfAbsent特性实现
     *
     * @param keyExtractor
     * @param <T>
     * @return
     */
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
    /**
     * 只获取重复的数据
     *
     * @param keyExtractor
     * @param <T>
     * @return
     */
    public static <T> Predicate<T> distinctNotByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) != null;
    }
}

导入这个工具类后怎么使用呢?我们接着往下看。

方法一根据指定字段去重

package com.jzmy.specialist.entity.util;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author mengzhichao
 * @create 2022-12-02-10:46
 */
public class Test {
    public static class Student{
        private String id;
        private String name;
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    public static void main(String[] args) {
        List<Student> list =new ArrayList<>();
        Student student =new Student();
        student.setId("1");
        student.setName("张三");
        list.add(student);
        Student student2 =new Student();
        student2.setId("1");
        student2.setName("张三");
        list.add(student2);
        Student student3 =new Student();
        student3.setId("1");
        student3.setName("李四");
        list.add(student3);
        Student student4 =new Student();
        student4.setId("2");
        student4.setName("王五");
        list.add(student4);
        System.out.println("未去重前list有几条数据:"+list.size());
        List<Student> rstList = list.stream().filter(DeduplicationUtil.distinctByKey(Student::getId)).collect(Collectors.toList());
        System.out.println("未去重前list有几条数据:"+rstList.size());
    }
}

List rstList = list.stream().filter(DeduplicationUtil.distinctByKey(Student::getId)).collect(Collectors.toList());


这段代码的意思是通过stream的filter方法进行过滤,过滤Id不相同的数据并通过collect方法收集为一个新的集合。


代码运行结果


3990be33ad6347fcb3c35d331416e208.png

方法二获取重复数据

package com.jzmy.specialist.entity.util;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author mengzhichao
 * @create 2022-12-02-10:46
 */
public class Test {
    public static class Student{
        private String id;
        private String name;
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    public static void main(String[] args) {
        List<Student> list =new ArrayList<>();
        Student student =new Student();
        student.setId("1");
        student.setName("张三");
        list.add(student);
        Student student2 =new Student();
        student2.setId("1");
        student2.setName("张三");
        list.add(student2);
        Student student3 =new Student();
        student3.setId("1");
        student3.setName("李四");
        list.add(student3);
        Student student4 =new Student();
        student4.setId("2");
        student4.setName("王五");
        list.add(student4);
        System.out.println("集合中的全部数据");
        for (int i=0;i<list.size();i++){
            System.out.println(list.get(i).getId());
            System.out.println(list.get(i).getName());
        }
        List<Student> rstList = list.stream().filter(DeduplicationUtil.distinctNotByKey(Student::getId)).collect(Collectors.toList());
        System.out.println("集合中的重复数据");
        for (int i=0;i<rstList.size();i++){
            System.out.println(rstList.get(i).getId());
            System.out.println(rstList.get(i).getName());
        }
    }
}

List rstList = list.stream().filter(DeduplicationUtil.distinctNotByKey(Student::getId)).collect(Collectors.toList());


这个和上面那个方法原理一样的只是换了一个调用方法而已。


代码运行结果

ec424a1599d942fabc1d097acad8d157.png




相关文章
|
1天前
|
Java API
Java 8新特性之Lambda表达式
【5月更文挑战第20天】本文将介绍Java 8中的一个重要特性——Lambda表达式。Lambda表达式是Java 8引入的一种新的编程语法,它允许我们将函数作为参数传递给方法,从而实现更加简洁、灵活的代码。本文将从Lambda表达式的基本概念、语法、使用方法以及优缺点等方面进行详细介绍,帮助读者更好地理解和应用Lambda表达式。
|
1天前
|
前端开发 Java
基于Java爬取微博数据(二) 正文长文本+导出数据Excel
【5月更文挑战第12天】基于Java爬取微博数据,正文长文本+导出数据Excel
|
1天前
|
Java 程序员 API
Java 8 Lambda 表达式和Stream API:概念、优势和实战应用
【5月更文挑战第20天】在Java 8中,Lambda 表达式和Stream API是两个非常强大的特性,它们显著改变了Java程序员处理数据和编写代码的方式。本篇技术文章将深入探讨这些特性的概念、优点,并提供实战示例,帮助理解如何有效地利用这些工具来编写更简洁、更高效的代码。
18 6
|
2天前
|
安全 Java 容器
Java一分钟之-并发编程:线程安全的集合类
【5月更文挑战第19天】Java提供线程安全集合类以解决并发环境中的数据一致性问题。例如,Vector是线程安全但效率低;可以使用Collections.synchronizedXxx将ArrayList或HashMap同步;ConcurrentHashMap是高效线程安全的映射;CopyOnWriteArrayList和CopyOnWriteArraySet适合读多写少场景;LinkedBlockingQueue是生产者-消费者模型中的线程安全队列。注意,过度同步可能影响性能,应尽量减少共享状态并利用并发工具类。
17 2
|
2天前
|
网络安全 流计算 Python
实时计算 Flink版操作报错合集之Flink sql-client 针对kafka的protobuf格式数据建表,报错:java.lang.ClassNotFoundException 如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
16 1
|
3天前
|
安全 Java 容器
Java一分钟之-高级集合框架:并发集合(Collections.synchronizedXXX)
【5月更文挑战第18天】Java集合框架的`Collections.synchronizedXXX`方法可将普通集合转为线程安全,但使用时需注意常见问题和易错点。错误的同步范围(仅同步单个操作而非迭代)可能导致并发修改异常;错误地同步整个集合类可能引起死锁;并发遍历和修改集合需使用`Iterator`避免`ConcurrentModificationException`。示例代码展示了正确使用同步集合的方法。在复杂并发场景下,推荐使用`java.util.concurrent`包中的并发集合以提高性能。
17 3
|
3天前
|
Java 开发者
Java一分钟之-高级集合框架:优先队列(PriorityQueue)
【5月更文挑战第18天】`PriorityQueue`是Java集合框架中的无界优先队列,基于堆数据结构实现,保证队头元素总是最小。常见操作包括`add(E e)`、`offer(E e)`、`poll()`和`peek()`。元素排序遵循自然排序或自定义`Comparator`。常见问题包括错误的排序逻辑、可变对象排序属性修改和混淆`poll()`与`peek()`。示例展示了自然排序和使用`Comparator`的排序方式。正确理解和使用`PriorityQueue`能提升应用性能。
36 6
|
3天前
|
存储 Java
Java一分钟之-高级集合框架:Queue与Deque接口
【5月更文挑战第18天】本文探讨Java集合框架中的`Queue`和`Deque`接口,两者都是元素序列的数据结构。`Queue`遵循FIFO原则,主要操作有`add/remove/element/peek`,空队列操作会抛出`NoSuchElementException`。`Deque`扩展`Queue`,支持首尾插入删除,同样需注意空`Deque`操作。理解并正确使用这两个接口,结合具体需求选择合适数据结构,能提升代码效率和可维护性。
29 4
|
4天前
|
Java API
Java 8新特性之Lambda表达式与Stream API
【5月更文挑战第17天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁。Stream API是一种用于处理集合的新工具,它提供了一种高效且易于使用的方式来处理数据。通过结合使用这两个特性,我们可以编写出更加简洁、高效的Java代码。
13 0
|
6天前
|
Java API
Java 8新特性之Lambda表达式与Stream API
【2月更文挑战第21天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给方法,从而使代码更加简洁、易读。Stream API是一种用于处理集合的新API,它提供了一种高效且易于使用的处理数据的方式。本文将通过实例讲解这两个特性的基本用法以及它们如何帮助我们编写更简洁、高效的Java代码。