簡體   English   中英

為什么java.util.Set不包含值getter? 有替代品嗎?

[英]Why java.util.Set does not contain value getter? Are there alternatives to it?

由於集合條目僅由屬性的子集( hashCode() + equals() )區分,因此有時需要對集合中包含的原始對象進行操作,這對於java.util.Set是不可能的。 我想出的唯一選擇是: Map<T, T> - 不是一個非常簡潔的解決方案。

收集框架中還有其他替代方案嗎? 要求是:O(1)獲取時間並且沒有基於hashCode() + equals()結果的重復。

如果還有一個O(1)操作沒有問題,你可以使用set.remove(Object)set.add(Object)方法對模擬 absenting方法get(Object) set.add(Object) 否則,我會使用你提到的Map<T,T>或帶底層地圖的簡單包裝類

編輯Set不包含get(Object)是你不需要返回你知道的對象。 如果您的對象包含在set中,您只需要檢查。

不是在java.util.Collections本身,而是使用Google Guava ,您可以使用Iterables.get從給定的Iterator檢索任何元素。

通常我不會提倡外部庫,但考慮到Guava是多么強大和有用,我認為沒有問題。

或者,您可以使用自己的實現迭代該集合。


另外,我在這里發現了一個非常有趣的線程來解釋這種行為。

Set不能包含兩個對象o1o2 ,以便o1.equals(o2 )(在此標准中不使用hashCode )。

HashSet正在使用散列圖來有效地存儲其對象,因此最終HashMap正是您基於hashCode()+equals()的操作所需要的。

如果你想重用它,我寫了這樣一個類。 Jayes包含一個類org.eclipse.recommenders.jayes.util.sharing.CanonicalSet ,它允許基於幾乎任何可以在hashCode()equals()實現中編碼的等價關系進行檢索。 我用它來構建數組等價類。 您可以查看CanonicalSet那些實現,它們位於同一個包中。

哦,但是,它也只是基於Map<Entry<T>,T> ,所以沒有什么神奇的。

基於HashMap的HashSet代碼非常簡單:如果你看一下它在JDK中的實現方式, 實際代碼的行很少(忽略構造函數和序列化代碼)。

在這樣做的方法是使用額外的get()方法實現自己的HashSet版本

public E get(Object o) {
   return map.get(o);
}

您可以使用commons-collections中的 SetUniqueList

它裝飾了一個java.util.List以確保不會像java.util.Set那樣存在重復項。

是的,它有點痛苦,無法分享同等對象。 Set API的問題是,缺少特定的addAndGet:

AddOnceSet<String> set = new AddOnceSet<>();
String s = in.readLine();
s = set.addOnce(s); // The new s is equal, and identical to the first added one.

s = set.getOnce(s);

不幸的是,這不適合集合API。 我希望這可能是Java 8+。 在Java 8中,您可以為addOncegetOnce添加一個默認接口。

像你說的那樣實現:

private Map<T, T> sharedThings = new HashMap<>().

public T shareThing(T s) {
    String t = sharedThings.get(s);
    if (t == null) {
        t = s;
        sharedStrings.put(t, t);
    }
    return t;
}

...

public void setT(T t) {
    this.t = sharedThing(t);
}

暫無
暫無

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

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