2015-04-25 42 views
0

我有一個地圖Map<String, SomeType>其中SomeType的每個實例都按照名稱添加,如map.put(object.getName(), object)。最後,map.values()中沒有重複。如何將Map.values作爲集合而不是集合?

現在,我想要一個Set<SomeType>從這張地圖沒有複製像new HashSet<>(map.values())

這是可能的,只與標準庫優惠嗎?

+1

它不是一個集合。你將不得不復制一份。或者只是使用收集,知道沒有重複。 – EJP

回答

5

您已經知道如何處理new HashSet<>(map.values())。您無法直接獲取一組值,因爲這些值可能包含重複項。即使在您的特定地圖中沒有重複值,但在一般地圖中,可能會有重複值。

你可以用Java 8 Streams做些什麼,但是它沒有明確的實例化Set。

Set<SomeType> values = map.values().stream().collect(Collectors.toSet()); 
2

沒有Collection包裝它是不可能的。

僅僅因爲在你的情況下沒有重複,這並不意味着他們不能。

Java Collections API允許您在Map中輸入重複值,所以合同必須返回Collection而不是Set

2

這將是一個簡單的事情,創造一個Set查看任何Collection的。

public final class SetView<E> extends AbstractSet<E> { 

    private final Collection<? extends E> collection; 

    private SetView(Collection<? extends E> collection) { 
     this.collection = collection; 
    } 

    public static <E> SetView<E> of(Collection<? extends E> collection) { 
     return new SetView<>(collection); 
    } 

    @Override 
    public boolean contains(Object e) { 
     return collection.contains(e); 
    } 

    // rest omitted. 
} 

有了這個,你可以再寫入Set<E> set = SetView.of(map.values());並向Map所有更改會自動在Set反映。

這種方法的問題是如果不復制Collection,某些方法將很難實現。例如,你會怎麼寫size()

最明智的辦法就是

@Override 
public int size() { 
    return new HashSet<>(collection).size(); 
} 

但這違背了使用一個視圖,而不是僅僅複製擺在首位的要素的目的。如果您知道Collection永遠不會包含重複的,你可以簡單

@Override 
public int size() { 
    return collection.size(); 
} 

不過,我會建議對這樣的做法。 A Map允許包含重複值,並且添加兩個具有相同值的條目的可能性意味着Set的合同將被打破。

除非你有不想複製元素的好理由,我只會用new HashSet<>(map.values())

相關問題