吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1751|回复: 11
收起左侧

[Java 原创] 基于Stream流的去重操作

  [复制链接]
mabin 发表于 2024-3-16 10:15
本帖最后由 mabin 于 2024-3-16 10:17 编辑

基于Stream流的去重操作,主要包括下面几种方式:

  • distinct 按照对象去重(实现 hashCode()和 equals()方法)
  • filter 按照对象属性去重(不需要实现 hashCode()和 equals()方法)
  • 利用stream的collectingAndThen+TreeSet去重(推荐)

去重实例对象

@Data
@AllArgsConstructor
public class Student implements Serializable{

    private static final long serialVersionUID = 8170834275910515552L;
    private String name;
    private Integer age;
    private Boolean sex;

}

distinct

    /**
     * distinct 按照对象去重(实现 hashCode()和 equals()方法)
     *
     * @Param students
     */
    public static void distinctHandleRepeat(List<Student> students) {
        students.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
    }

filter

    /**
     * filter 按照对象属性去重(不需要实现 hashCode()和 equals()方法)
     * 单属性去重
     * 多属性去重(例如: 根据age去重后,再根据sex再次进行去重)
     *
     * @param students
     */
    public static void filterHandleRepeat(List<Student> students) {
        students.stream()
                .filter(filterByKey(Student::getAge))
                .filter(filterByKey(Student::getSex))
                .forEach(System.out::println);
    }

    /**
     * putIfAbsent(): key存在时不添加到map并返回value,不存在时则添加返回null
     *
     * @param keyExtractor
     * @param <T>
     * @return
     */
    public static <T> Predicate<T> filterByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>(16);
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

TreeSet(推荐)

    /**
     * 利用stream的collectingAndThen+TreeSet去重
     *
     * @param students
     */
    public static void collectingAndThenHandleRepeat(List<Student> students) {
        students.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getAge))), ArrayList::new))
                .forEach(System.out::println);
    }

调用示例

    public static void main(String[] args) {
        // distinct去重
        distinctHandleRepeat(getStudents());
        System.out.println("================================================");
        // filter去重
        filterHandleRepeat(getStudents());
        System.out.println("================================================");
    // collectingAndThen+TreeSet去重
        collectingAndThenHandleRepeat(getStudents());
    }

    public static List<Student> getStudents() {
        List<Student> students = new ArrayList<>();
        students.add(new Student("Tom", 25, Boolean.TRUE));
        students.add(new Student("Jack", 23, Boolean.TRUE));
        students.add(new Student("Top", 22, Boolean.FALSE));
        students.add(new Student("Gao", 22, Boolean.FALSE));
        students.add(new Student("Top", 22, Boolean.FALSE));
        return students;
    }

测试结果

Student(name=Tom, age=25, sex=true)
Student(name=Jack, age=23, sex=true)
Student(name=Top, age=22, sex=false)
Student(name=Gao, age=22, sex=false)
================================================
Student(name=Tom, age=25, sex=true)
Student(name=Top, age=22, sex=false)
================================================
Student(name=Top, age=22, sex=false)
Student(name=Jack, age=23, sex=true)
Student(name=Tom, age=25, sex=true)

推荐利用stream的collectingAndThen+TreeSet去重,灵活度和简洁度都较高


免费评分

参与人数 3吾爱币 +7 热心值 +3 收起 理由
douNiWan111 + 1 我很赞同!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
ultral87 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

allxxall 发表于 2024-11-13 10:59
Java中对存在存储结构的对象data的处理,可以使用stream和for循环处理;
其中如果是简单的数据处理,就没有必要使用stream,直接for循环即可,因为这样做没有额外的性能消耗且简单易懂;
在对于stream的使用中,存在顺序流和并行流,如果其中要处理的数据量太大就可以考虑其中的并行流处理数据,将其分成多个线程处理;
当前了,如果数据量是中等规模的话,就没有必要使用并行流,毕竟并行流的开启和管理使用的消耗也不小
如果有什么遗漏的,欢迎大家补充
jstar 发表于 2024-3-16 10:49
crystalZ 发表于 2024-3-16 10:52
jinwuxiong 发表于 2024-3-16 11:17
谢谢分享
TabKey9 发表于 2024-3-16 13:41
不错不错
RabbitBearLove 发表于 2024-3-16 15:13
谢谢分享,很实用
 楼主| mabin 发表于 2024-3-18 13:50
sherlocked1314 发表于 2024-3-18 13:27
不错的去重方式,很棒,我也是java选手,好好奇啥业务会用到stream流的去重啊

某些直接操作DB无法灵活达到去重要求的时候,可以使用这种stream流方式
yangxia98 发表于 2024-7-29 10:36
又学会了一招
liilong 发表于 2024-7-30 09:16
使用stream就是简洁
StoreDS 发表于 2024-10-20 23:12
有些场景确实使用stream去重更方便快捷
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 13:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表