Java 8 Stream.distinct()
方法用于过滤或者收集流中的所有不同元素。
Stream distinct() 方法
distict()
方法是一种有状态的中间操作,它在处理新元素时使用先前看到的元素的状态。
Stream<T> distinct()
此方法返回由给定流中不同元素组成的流。
检查对象是否相等,使用equals() 方法。
对于有序流,会保留遇到顺序中最先出现的元素。
对于无序流,不保证保留的元素。
https://onitroad.com 更多教程
Stream distinct() 示例
从列表中找出所有不同字符串
在给定的示例中,我们有一个字符串列表,我们想找到所有不同的字符串。
我们将使用 Stream.collect()
终端操作将这些不同的值收集到另一个 List
中。
收集不同的元素后,我们将通过将它们打印到控制台来验证它。
Collection<String> list = Arrays.asList("A", "B", "C", "D", "A", "B", "C"); // 获取不包含重复项的集合,例如:distinct only List<String> distinctElements = list.stream() .distinct() .collect(Collectors.toList()); // 查看不同的元素 System.out.println(distinctElements);
使用 distinctByKey() 通过字段值查找所有不同的对象
在实时应用程序中,我们将处理对象流或者复杂类型(代表某些系统实体),而且这些是字符串常量或者原始类型的可能性很小。
因此,让我们扩展我们的示例以处理复杂类型(例如类)并对对象键应用过滤。
Java 没有任何原生 API 可以直接按对象属性过滤不同的对象,因此我们将创建一个实用程序函数然后使用它。
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) { Map<Object, Boolean> map = new ConcurrentHashMap<>(); return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; }
上面的 distinctByKey() 函数使用 ConcurrentHashMap 实例来找出是否存在任何具有相同值的现有键,其中键是从函数引用中获得的。
我们将传递对象的属性 getter 方法,该方法将使属性值充当映射的键。
import java.util.Arrays; import java.util.Collection; 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 JavaStreamDistinctExamples { public static void main(String[] args) { Person JackLi = new Person(1, "JackLi", "Gupta"); Person BobRobert = new Person(2, "BobRobert", "Clooney"); Person JackLi = new Person(3, "JackLi", "Kolen"); //Add some random persons Collection<Person> list = Arrays.asList(JackLi,BobRobert,JackLi,JackLi,BobRobert,JackLi); // Get distinct objects by key List<Person> distinctElements = list.stream() .filter( distinctByKey(p -> p.getId()) ) .collect( Collectors.toList() ); // Let's verify distinct elements System.out.println( distinctElements ); } //Utility function public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) { Map<Object, Boolean> map = new ConcurrentHashMap<>(); return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } } //Model class class Person { public Person(Integer id, String fname, String lname) { super(); this.id = id; this.fname = fname; this.lname = lname; } private Integer id; private String fname; private String lname; //Getters and Setters @Override public String toString() { return "Person [id=" + id + ", fname=" + fname + ", lname=" + lname + "]"; } }
日期:2020-09-17 00:10:03 来源:oir作者:oir