Java8中Stream对列表去重的方法有哪些?
1. 去重
-
distinct()是Java 8 中 Stream 提供的方法,返回的是由该流中不同元素组成的流。
-
distinct()使用 hashCode() 和 eqauls() 方法来获取不同的元素。
-
因此,需要去重的类必须实现 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