2012-02-08 33 views
3

我有一個Set對象,我使用這個集合來確保當我向該集合中添加一個元素時,它不會被添加。這是比較容易的部分,只要使用Set.add();但這完成後我需要參考設置的對象。獲取對集合中的副本的引用

我的意思是有.add()不返回布爾值,但是你試圖添加的實際對象(如果它沒有被添加,那麼在集合中)。是否已經有一個Set實現來實現這個功能,還是我必須自己寫?

此刻我使用了Set.add(),如果它返回false,我使用迭代器來查找集合中的一個。雖然這有效,但我覺得它很難看。特別是在使用HashSet實現時,應該能夠使用hashcode更快地找到對象。有任何想法嗎?

編輯:哇,在很短的時間內答案很多,謝謝。好了,我想要做的就是創建一個從一些地方加載數據,並根據其創建對象一定的數據結構。該數據可能包含重複的,如果我用一組和只需要這一個組,但數據結構需要將引用添加到這些獨特的對象在數據結構的其他對象,這將不會是一個問題,所以我需要引用集合中的(唯一)對象。此外,我不能只是沒有加載已經包含在該組中的數據,因爲有鏈接到它的更多(唯一)的數據,這也增加,與已經包含在設置爲數據的引用一起。爲了說明的目的(因爲上面的解釋是遠不清楚),我會在這裏給出一個例子:

數據:

 
foo  bar 
1  3 
1  4 
2  5 

數據結構網絡化:

Set<Foo> totalFooSet 
Set<Bar> totalBarSet 

富:

sometype data 
Set<Bar> barSet 

酒吧:

sometype data 
Set<Foo> fooSet 

這有點像多對多的關係。

我不確定這裏是否有一些主要的設計缺陷,我已經與其他人一起查看過,我們無法弄清楚如何以不同的方式做到這一點。我喜歡使用的HashMap的想法,所以我將創建一個子類,並添加一個addAndReturn()函數來了。

+6

但是如果你添加一個元素並且'add'返回'false',那麼你**知道**重複的元素是你正在嘗試添加的元素! – vulkanino 2012-02-08 09:25:06

+1

除非你嚴重強姦Object.equals()'的合約,否則不需要這樣做,因爲不會被添加到Set的對象與已經在該集合中的對象相同。只要使用你已有的對象。如果你設法打破equals(),你應該使用其他方法,例如使用'Map'。 – Bombe 2012-02-08 09:29:52

+1

你能解釋這種情況下的用例嗎?我很想知道爲什麼你需要參考原始對象? – beny23 2012-02-08 09:30:38

回答

4

類似於肖恩的答案(我upvoted),但可能更可重用。

public class HashMapBackedSet<T> extends HashMap<T,T>{ 
    public T add(T toAdd){ 
     T existing = get(toAdd); 
     if(existing != null){ 
      return existing; 
     } 
     put(toAdd, toAdd); 
     return toAdd; 
    } 
} 
-1

將你的設置放在一個類中,當你調用add時返回該對象。

0

Set不能包含重複條目。設定的目的不是爲了做到這一點。 據我所知,你想要參考以前的對象與你現在試圖添加的對象相同。 您不必重複設置的找到這個對象。只是用戶oldObject = set.get(newObject)

該操作與通過索引獲取數組元素一樣快。

+0

http://docs.oracle.com/javase/6/docs/api/java/util/Set.html不幸的是,Set沒有get(blah)方法。 – 2012-02-08 09:31:45

5

(如@AlexR說,我假設你想等於你想現在添加的一個參考以前對象)

而不是使用一組,請嘗試使用一個HashMap與一個關鍵字和一個值相同的對象。然後,你可以做到以下幾點:

Foo objectToAdd = //obtained the normal way 
Map<Foo,Foo> psuedoSet = //this is stored somewhere 

Foo result = psuedoSet.get(objectToAdd); 
if (result == null) { 
    pseudoSet.put(objectToAdd, objectToAdd); 
    result = objectToAdd; 
} 
return result; 
+0

這是什麼意思? – UmNyobe 2012-02-08 09:34:24

3

如果我理解正確的話,如果你只是想添加的元素已經包含在集,您想這已經是在集(這是等於實例增加了一個,但不一定相同)?

此行爲是由Google Guavainterners提供:

Interner<Object> interner = Interners.newStrongInterner(); 
Object objectInSet = interner.intern(otherObject); 

不幸的是,interners不提供任何其他的方法,比如迭代其包含的值,所以用它們作爲一組替代是不可能的爲你。

另一個選項是HashMap<T, T>,其中存儲從每個對象到它自己的映射。然後,您可以通過調用get()輕鬆獲得已包含對象的引用。如果您不介意該對象始終被覆蓋,只需撥打put()即可返回您想要的對象(之前存儲的對象)。

+0

+1,用於對比_identity_和_equality_,後者@FinalArt已被覆蓋。 – Tim 2012-02-08 11:30:41