簡體   English   中英

相當於使用自定義比較器流不同

[英]Equivalent to stream distinct using a custom comparator

如果我有以下列表:

List<String> list = Arrays.asList("hello", "world", "hello");

我應用以下(Java8):

list.stream().distinct().collect(Collectors.toString());

然后我會得到一個“hello”和“world”的列表。

但是,在我的情況下,我有一個類型的列表(從外部api)我想“繞過”等於方法,理想情況下使用比較器,因為它不包括我需要的。

假設這個類看起來像這樣:

public class Point {
    float x;
    float y;
    //getters and setters omitted
}

在這種情況下,我想要將兩個要點定義為相等的標准,例如(30,20)和(30.0001,19.999)。

一個自定義比較器可以做到這一點,但我發現沒有API可以執行Java8 Stream中的distinct(),而是使用比較器(或類似的模式)。

有什么想法嗎? 我知道我可以編寫這樣的函數,但我更喜歡使用現有apis的優雅方式...我對外部庫沒有限制(如果他們有一個舒適的做法,guava,apache-commons等是受歡迎的我需要的)。

HashingStrategy是您正在尋找的概念。 它是一個策略接口,允許您定義equals和hashcode的自定義實現。

public interface HashingStrategy<E>
{
    int computeHashCode(E object);
    boolean equals(E object1, E object2);
}

Streams不支持散列策略,但Eclipse Collections不支持散列策略。 它具有支持散列策略的集合和映射,以及采用散列策略的distinct()等方法的重載。

這對字符串很有用。 例如,這是我們如何讓所有不同的字符串忽略大小寫。

MutableList<String> strings = Lists.mutable.with("Hello", "world", "HELLO", "World");
assertThat(
    strings.distinct(HashingStrategies.fromFunction(String::toLowerCase)),
    is(equalTo(Lists.immutable.with("Hello", "world"))));

或者您可以手動編寫散列策略以避免垃圾創建。

HashingStrategy<String> caseInsensitive = new HashingStrategy<String>()
{
    @Override
    public int computeHashCode(String string)
    {
        int hashCode = 0;
        for (int i = 0; i < string.length(); i++)
        {
            hashCode = 31 * hashCode + Character.toLowerCase(string.charAt(i));
        }
        return hashCode;
    }

    @Override
    public boolean equals(String string1, String string2)
    {
        return string1.equalsIgnoreCase(string2);
    }
};

assertThat(
    strings.distinct(caseInsensitive),
    is(equalTo(Lists.immutable.with("Hello", "world"))));

這也適用於Points,但前提是您可以將非重疊區域內的所有點分組以具有相同的哈希碼。 如果您使用的比較器定義為當兩個點足夠接近時返回0,則可能會遇到傳遞性問題。 例如,點A,B和C可以沿A線和C線下降,它們都接近B但彼此相距很遠。 盡管如此,如果這對您來說是一個有用的概念,我們歡迎將ListIterable.distinct(Comparator)添加到API的拉取請求。

注意:我是Eclipse Collections的提交者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM