2009-09-15 38 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的实现。

相关问题