Java Stream different()函数删除重复项
Java Stream独特的()方法返回一个新的独特元素流。
在处理集合中的重复元素之前非常有用。
Java Stream different()方法
使用equals()方法比较元素。
因此,流元素必须正确实现equals()方法。如果流是有序的,则遇到顺序将保留。
这意味着首先出现的元素将出现在不同的元素流中。如果流是无序的,那么生成的流元素可以是任何顺序。
流distinct()是有状态的中间操作。
由于有很大的缓冲开销,因此对有序并行流使用distinct()可能会导致性能下降。
在这种情况下,请进行顺序流处理。
使用distinct()删除重复元素
让我们来看看如何使用stream different()方法从集合中删除重复的元素。
jshell> List<Integer> list = List.of(1, 2, 3, 4, 3, 2, 1); list ==> [1, 2, 3, 4, 3, 2, 1] jshell> List<Integer> distinctInts = list.stream().distinct().collect(Collectors.toList()); distinctInts ==> [1, 2, 3, 4]
Java Stream different()示例
使用Stream different()和forEach()仅处理唯一元素
由于distinct()是中间操作,因此我们可以将forEach()方法与它一起使用以仅处理唯一元素。
jshell> List<Integer> list = List.of(1, 2, 3, 4, 3, 2, 1); list ==> [1, 2, 3, 4, 3, 2, 1] jshell> list.stream().distinct().forEach(x -> System.out.println("Processing " + x)); Processing 1 Processing 2 Processing 3 Processing 4
Java Stream different()forEach()示例
使用自定义对象流distinct()
让我们看一个简单的示例,该示例使用distinct()从列表中删除重复的元素。
package com.theitroad.java; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class JavaStreamDistinct { public static void main(String[] args) { List<Data> dataList = new ArrayList<>(); dataList.add(new Data(10)); dataList.add(new Data(20)); dataList.add(new Data(10)); dataList.add(new Data(20)); System.out.println("Data List = "+dataList); List<Data> uniqueDataList = dataList.stream().distinct().collect(Collectors.toList()); System.out.println("Unique Data List = "+uniqueDataList); } } class Data { private int id; Data(int i) { this.setId(i); } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return String.format("Data[%d]", this.id); } }
输出:
Data List = [Data[10], Data[20], Data[10], Data[20]] Unique Data List = [Data[10], Data[20], Data[10], Data[20]]
unique()方法并未删除重复的元素。
这是因为我们没有在Data类中实现equals()方法。
因此,使用超类Object equals()方法来标识相等的元素。
Object类的equals()方法实现为:
public boolean equals(Object obj) { return (this == obj); }
由于数据对象具有相同的ID,但它们引用的是不同的对象,因此认为它们不相等。
这就是为什么如果您打算对自定义对象使用流different()方法,那么实现equals()方法非常重要。
请注意,Collection类API使用equals()和hashCode()方法来检查两个对象是否相等。
因此最好为它们两个都提供一个实现。
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; return result; } @Override public boolean equals(Object obj) { System.out.println("Data equals method"); if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Data other = (Data) obj; if (id != other.id) return false; return true; }
提示:您可以使用" Eclipse>源>生成equals()和hashCode()"菜单选项轻松地生成equals()和hashCode()方法。
添加equals()和hashCode()实现后的输出为:
Data List = [Data[10], Data[20], Data[10], Data[20]] Data equals method Data equals method Unique Data List = [Data[10], Data[20