2009-09-15 130 views

回答

813
Set<Foo> foo = new HashSet<Foo>(myList); 
+52

這將拋出NullPointerException如果列表爲空 – Ashish 2014-05-13 14:46:18

+87

@Ashish:這是完全不相關的問題。沒有人問如何將null轉換爲Set。總是要求處理null的人是Java(文化)如何被破壞的標誌。幾乎總是,null是一個錯誤。拋出異常實際上是你能做的最好的事情。特別是當它是對集合的空引用時:您多久可以想象集合的空引用的語義含義 - 並且這樣的含義與空集合不同? – 2016-02-06 16:34:33

+2

同意,而不是null,您應該(幾乎)始終傳遞:bean的不可變靜態空實例,或Collection.emptyXXX()。如果它在每個方法開始時沒有被空值檢查污染,它也使得你的代碼更容易閱讀。 – 2016-10-17 09:20:02

112

我同意sepp2k,但也有可能的一些其他細節:

new HashSet<Foo>(myList); 

會給你一個無序集不有重複。在這種情況下,使用對象上的.equals()方法識別重複。這與.hashCode()方法結合使用。 (欲瞭解更多關於平等看看here

,給出了一個有序集合另一種方法是:

new TreeSet<Foo>(myList); 

這個工作,如果美孚實現媲美。如果沒有,那麼你可能需要使用一個比較:

Set<Foo> lSet = new TreeSet<Foo>(someComparator); 
lSet.addAll(myList); 

這取決於任何的compareTo()(從可比接口)或比較()(從比較器),以確保其唯一性。所以,如果您只關心唯一性,請使用HashSet。如果您在排序後,請考慮TreeSet。 (記住:稍後優化!)如果時間效率問題在空間效率問題上使用HashSet,請查看TreeSet。請注意,更高效的Set和Map實現可以通過Trove(和其他位置)獲得。

58

如果你使用Guava庫:

Set<Foo> set = Sets.newHashSet(list); 

,或者更好:

Set<Foo> set = ImmutableSet.copyOf(list); 
+11

+1使用ImmutableSet – tomrozb 2013-05-03 14:28:44

+1

ImmutableSet.copyOf爲什麼更好? – user672009 2016-04-14 09:05:39

+1

Guava的newHashSet()對基本的Java新HashSet()有什麼優勢? – 2016-05-16 15:20:36

14
Set<E> alphaSet = new HashSet<E>(<your List>); 

或完整的例子

import java.util.ArrayList; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 

public class ListToSet 
{ 
    public static void main(String[] args) 
    { 
     List<String> alphaList = new ArrayList<String>(); 
     alphaList.add("A"); 
     alphaList.add("B"); 
     alphaList.add("C"); 
     alphaList.add("A"); 
     alphaList.add("B"); 
     System.out.println("List values ....."); 
     for (String alpha : alphaList) 
     { 
      System.out.println(alpha); 
     } 
     Set<String> alphaSet = new HashSet<String>(alphaList); 
     System.out.println("\nSet values ....."); 
     for (String alpha : alphaSet) 
     { 
      System.out.println(alpha); 
     } 
    } 
} 
+1

+1爲一個完整的代碼示例。此處還有一點需要注意的是,哈希不保證從運行到運行都是相同的。這意味着在「設置值.....」後面打印的列表可能是「ABC」一次運行,「CBA」另一次運行。正如我在我的回答中提到的那樣,您可以使用樹組來獲得穩定的順序。另一種選擇是使用LinkedHashSet,它記住項目添加到它的順序。 – Spina 2013-09-23 12:45:32

9

我會在轉換之前進行空檢查設置。

if(myList != null){ 
Set<Foo> foo = new HashSet<Foo>(myList); 
} 
+3

或'設置 foo = myList == null? Collections.emptySet():new HashSet (myList);' – vegemite4me 2014-12-30 14:29:35

5

您可以轉換List<>Set<>

Set<T> set=new HashSet<T>(); 

//Added dependency -> If list is null then it will throw NullPointerExcetion. 

Set<T> set; 
if(list != null){ 
    set = new HashSet<T>(list); 
} 
+0

我想你的意思是將它從List設置爲Set。 – Simon 2014-12-27 15:49:50

17

用java 8,你可以使用流:

List<Integer> mylist = Arrays.asList(100, 101, 102); 
Set<Integer> myset = mylist.stream().collect(Collectors.toSet())); 
+5

你檢查過這個表現嗎?這會做一個迭代+迭代器,一個新的HashSet(),然後爲每個列表項添加一個addAll()調用。總的來說,cca。創建了5個對象,像一個新的HashSet(列表)一樣簡單。 – 2016-10-17 09:17:54

2

有各種不同的方式來獲得一個Set爲:

List<Integer> sourceList = new ArrayList(); 
    sourceList.add(1); 
    sourceList.add(2); 
    sourceList.add(3); 
    sourceList.add(4); 

    // Using Core Java 
    Set<Integer> set1 = new HashSet<>(sourceList); //needs null-check if sourceList can be null. 

    // Java 8 
    Set<Integer> set2 = sourceList.stream().collect(Collectors.toSet()); 
    Set<Integer> set3 = sourceList.stream().collect(Collectors.toCollection(HashSet::new)); 

    //Guava 
    Set<Integer> set4 = Sets.newHashSet(sourceList); 

    // Apache commons 
    Set<Integer> set5 = new HashSet<>(4); 
    CollectionUtils.addAll(set5, sourceList); 

當我們使用Collectors.toSet()時,它返回一個集合並按照文檔:There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned。如果我們想獲得HashSet,那麼我們可以使用另一種替代方法來獲得一組(檢查set3)。

3

對於Java 8這很容易:

List <UserEntity> vList= new ArrayList<UserEntity>(); 
vList= service(...); 
Set<UserEntity> vSet= vList.stream().collect(Collectors.toSet()); 
2

讓我們不要忘記我們的相對較新的朋友,流API。 如果你將其轉換爲一組前需要預處理列表,最好是有類似:

list.stream().<here goes some preprocessing>.collect(Collectors.toSet()); 
0

Optional.ofNullable

Set<Foo> mySet = Optional.ofNullable(myList).map(HashSet::new).orElse(null); 
0

一個更多的Java 8彈性的解決方案使用Java 10,你現在就可以使用Set#copyOf容易地一個List<E>轉換爲不可修改Set<E>

實施例:

var set = Set.copyOf(list); 

請記住,這是一個無序的操作,並null元素允許的,因爲它會拋出一個NullPointerException

如果您希望它是可修改的,那麼只需將它傳遞給構造函數Set的實現。

相關問題