介绍
java8 Stream 提供的distinct()功能用于对流中的多个元素进行去重处理,并返回由不同元素组成的流。
stream.distinct对List<String>去重
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDistinctDemo {
public static void main(String[] args) {
String[] strArr = new String[]{"aaa", "bbb", "ccc", "aac", "bbb", "aac"};
List<String> stringList = Arrays.asList(strArr);
System.out.println("List<String> 的情况——去重操作之前:" + stringList);
stringList = stringList.stream().distinct().collect(Collectors.toList());
System.out.println("List<String> 的情况——去重操作之后:" + stringList);
}
}
执行结果:
List<String> 的情况——去重操作之前:[aaa, bbb, ccc, aac, bbb, aac]
List<String> 的情况——去重操作之后:[aaa, bbb, ccc, aac]
stream.distinct对List<Integer>去重
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDistinctDemo {
public static void main(String[] args) {
Integer[] intArr = new Integer[]{1, 4, 2, 5, 2, 5, 8, 2, 9};
List<Integer> integerList = Arrays.asList(intArr);
System.out.println("List<Integer> 的情况——去重操作之前:" + integerList);
integerList = integerList.stream().distinct().collect(Collectors.toList());
System.out.println("List<Integer> 的情况——去重操作之后:" + integerList);
}
}
执行结果:
List<Integer> 的情况——去重操作之前:[1, 4, 2, 5, 2, 5, 8, 2, 9]
List<Integer> 的情况——去重操作之后:[1, 4, 2, 5, 8, 9]
stream.distinct对List<Object>去重
distinct()使用Object的 equals() 方法判断元素是否重复。
Object.equals() 通过判断两个对象是否引用同一个地址来判定是否相等。
基于以上,当我们需要对Class 对象进行distinct时,需要进行重写equals()方法。
但是,equals()重写时hashCode()必须重写,所以类的hashCode()方法也必须重写。
定义类
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return String.format(java.util.Locale.ROOT, "[%s, %d]", this.name, this.age);
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
final Person person = (Person) obj;
if (this == person) {
return true;
} else {
return (this.name.equals(person.name) && this.age == person.age);
}
}
@Override
public int hashCode() {
int hashno = 7;
hashno = 13 * hashno + (name == null ? 0 : name.hashCode()) + age;
return hashno;
}
}
去重操作
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDistinctDemo {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("aa", 18));
personList.add(new Person("bb", 19));
personList.add(new Person("aa", 18));
personList.add(new Person("aa", 19));
System.out.println("List<Person> 的情况——去重操作之前:" + personList);
List<Person> personList1 = personList.stream().distinct().collect(Collectors.toList());
System.out.println("List<Person> 的情况——去重操作之后:" + personList1);
}
}
执行结果:
List<Person> 的情况——去重操作之前:[[aa, 18], [bb, 19], [aa, 18], [aa, 19]]
List<Person> 的情况——去重操作之后:[[aa, 18], [bb, 19], [aa, 19]]
基于Class属性对Object去重
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class StreamDistinctDemo {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("aa", 18));
personList.add(new Person("bb", 19));
personList.add(new Person("aa", 18));
personList.add(new Person("aa", 19));
System.out.println("List<Person> 的情况——去重操作之前:" + personList);
List<Person> personList1 = personList.stream().filter(distinctByKey(d->d.name)) .collect(Collectors.toList());
System.out.println("List<Person> 的情况——去重操作之后:" + personList1);
}
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;
}
}
执行结果:
List<Person> 的情况——去重操作之前:[[aa, 18], [bb, 19], [aa, 18], [aa, 19]]
List<Person> 的情况——去重操作之后:[[aa, 18], [bb, 19]]