Java8中Stream对列表去重的方法有哪些?

1. 去重

  1. distinct()是Java 8 中 Stream 提供的方法,返回的是由该流中不同元素组成的流。

  2. distinct()使用 hashCode() 和 eqauls() 方法来获取不同的元素。

  3. 因此,需要去重的类必须实现 hashCode() 和 equals() 方法。换句话讲,我们可以通过重写定制的 hashCode() 和 equals() 方法来达到某些特殊需求的去重。

distinct() 方法声明如下:

Stream<T> distinct();

1.1 对于 String 列表的去重

因为 String 类已经覆写了 equals() 和 hashCode() 方法,所以可以去重成功。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author LanceQ
 * @version 1.0
 * @time 2021/5/10 17:27
 */
public class listDistinctByStreamDistinct {
    public static void main(String[] args) {
        // 1. 对于 String 列表去重
        List<String> stringList = new ArrayList<String>() {{
            add("A");
            add("A");
            add("B");
            add("B");
            add("C");
        }};
        System.out.print("去重前:");
        for (String s : stringList) {
            System.out.print(s);
        }
        System.out.println();
        stringList=stringList.stream().distinct().collect(Collectors.toList());
        System.out.print("去重后:");
        for (String s : stringList) {
            System.out.print(s);
        }
        System.out.println();
    }
}

运行结果:
去重前:AABBC
去重后:ABC

1.2 对于实体类列表的去重

  • 需要注意的是如果你想看到你添加进去的参数,要重新toString()方法,如果要实现通过stream().distinct()去重的话,那么需要给Student类重写equals() 以及 hashCode() 方法,否则的话就会去重失败。
import java.util.Objects;

/**
 * @author LanceQ
 * @version 1.0
 * @time 2021/5/11 16:24
 */

public class Student {
    private int strNo;
    private String Name;

    @Override
    public String toString() {
        return "Student{" +
                "strNo=" + strNo +
                ", Name='" + Name + '\'' +
                '}';
    }

    public int getStrNo() {
        return strNo;
    }

    public void setStrNo(int strNo) {
        this.strNo = strNo;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(strNo, Name);
    }
}

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author LanceQ
 * @version 1.0
 * @time 2021/5/11 16:30
 */
public class StudentDemo {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();

        for (int i = 0; i < 3; i++) {
            Student s = new Student();
            s.setName("a");
            s.setStrNo(i);
            students.add(s);
        }

        for (int i = 0; i < 2; i++) {
            Student s = new Student();
            s.setName("a");
            s.setStrNo(i);
            students.add(s);
        }
        System.out.println("去重前:");
        System.out.println(students);

        System.out.println("去重后");
        students=students.stream().distinct().collect(Collectors.toList());
        System.out.println(students);
    }
}

运行结果:
去重前:
[Student{strNo=0, Name='a'}, Student{strNo=1, Name='a'}, Student{strNo=2, Name='a'}, Student{strNo=0, Name='a'}, Student{strNo=1, Name='a'}]
去重后
[Student{strNo=0, Name='a'}, Student{strNo=1, Name='a'}, Student{strNo=2, Name='a'}]

2. 根据List中 Object 某个属性去重

2.1 在上面的Students类和实现方法的基础上

  • 并且这种方法不需要重新Student类中的equals和hashCode方法。
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/**
 * @author LanceQ
 * @version 1.0
 * @time 2021/5/11 16:30
 */
public class StudentDemo {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();

        for (int i = 0; i < 3; i++) {
            Student s = new Student();
            s.setName("a");
            s.setStrNo(i);
            students.add(s);
        }

        for (int i = 0; i < 2; i++) {
            Student s = new Student();
            s.setName("a");
            s.setStrNo(i);
            students.add(s);
        }
        System.out.println("去重前:");
        System.out.println(students);

        System.out.println("distinct去重后");
        students=students.stream().distinct().collect(Collectors.toList());
        System.out.println(students);
        // 这里我们引入了两个静态方法,以及通过 TreeSet<> 来达到获取不同元素的效果
        // 1. import static java.util.stream.Collectors.collectingAndThen;
        // 2. import static java.util.stream.Collectors.toCollection;
        students=students.stream().collect(
                collectingAndThen(
                        toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new)
        );
        System.out.println("根据name去重");
        System.out.println(students);
    }
}

运行结果:
去重前:
[Student{strNo=0, Name='a'}, Student{strNo=1, Name='a'}, Student{strNo=2, Name='a'}, Student{strNo=0, Name='a'}, Student{strNo=1, Name='a'}]
distinct去重后
[Student{strNo=0, Name='a'}, Student{strNo=1, Name='a'}, Student{strNo=2, Name='a'}]
根据name去重
[Student{strNo=0, Name='a'}]

参考:https://mp.weixin.qq.com/s/yiRO0-nNvzlJ84cipHu6mg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值