如果我有以下列表:等效使用自定義比較以流不同
List<String> list = Arrays.asList("hello", "world", "hello");
我申請以下(Java8):
list.stream().distinct().collect(Collectors.toString());
然後我會得到一個「Hello列表「和」世界「。但是,就我而言,我有一個類型(來自外部api)的列表,我想繞過equals方法,理想情況下使用比較器,因爲它不包含我需要的東西。
假設這個類看起來像這樣:
public class Point {
float x;
float y;
//getters and setters omitted
}
在這種情況下,我想的是覆蓋一定的標準的兩點被定義爲相等的,例如(30,20)和(30.0001,19.999 )。
一個自定義的比較器可以做到這一點,但我沒有找到API來做Java8 Stream中的distinct(),但是使用比較器(或類似模式)。
有什麼想法?我知道我可以編寫這樣一個函數,但我寧願喜歡使用現有API的優雅方式......我對外部庫(番石榴,apache-commons等)沒有限制,只要它們有一個舒適的方式我需要的)。
這是一個類似的討論,但試圖用Set實現:http://stackoverflow.com/questions/14880450/java-hashset-with-a-custom-equality-criteria。我認爲我所遵循的方法朝着正確的方向發展。有沒有可以做這種事情的API? – Martin
來自doc:distinct() 返回由此流的不同元素(根據Object.equals(Object))組成的流。您可以在您的特定情況下覆蓋Point類中的equals方法。另外,不同的是有狀態的管道操作。您可以嘗試使用過濾器代替:[示例](http://stackoverflow.com/questions/23699371/java-8-distinct-by-property) – algor
一個比較器(或一個equals()方法),將執行相等你所描述的會打破Comparator(或等於)的合約。事實上,如果兩個點如果彼此接近(假設在兩個方向上最多爲0.1),那麼它表示等於'(0.9,0.9)',並且'(0.9,0.9)'等於'(0.8,0.8)'。但是,通過傳遞性(由比較合同規定),'(1,1)'也必須等於'(0.8,0.8)',這不是你想要的。 –