Java 如何收集流中不同的元素

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