用Java将列表转换为集合的最简单方法


627

在Java中将Lista 转换为a 的最简单方法是什么Set

Answers:


1065
Set<Foo> foo = new HashSet<Foo>(myList);

3
虽然正确,但此答案缺乏足够的技术背景,无法保证是最佳/可接受的答案,因为这里存在陷阱,具体取决于的实现方式SetMap所使用的实现方式;HashSet认为在这里。
Madbreaks '18

145

我同意sepp2k,但还有其他一些细节可能很重要:

new HashSet<Foo>(myList);

将为您提供没有重复的未排序集合。在这种情况下,将在对象上使用.equals()方法来标识重复项。可以与.hashCode()方法结合使用。(有关平等的更多信息,请点击此处

提供排序集的替代方法是:

new TreeSet<Foo>(myList);

如果Foo实现了Comparable,则此方法有效。如果不是,那么您可能要使用比较器:

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

这依赖于compareTo()(来自可比较的接口)或compare()(来自比较器)以确保唯一性。因此,如果您只关心唯一性,请使用HashSet。如果要进行排序,请考虑使用TreeSet。(请记住:稍后进行优化!)如果时间效率很重要,而空间效率很重要,请使用HashSet,请查看TreeSet。请注意,可以通过Trove(和其他位置)使用Set和Map的更有效实现。


感谢您提供自定义的比较器用例!
贾斯汀·帕佩兹

70

如果您使用Guava库:

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

或更好:

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

2
为什么ImmutableSet.copyOf更好?
user672009 '16

1
与基本的Java new HashSet()相比,番石榴的newHashSet()有什么优势?
Nelda.techspiress

@ Nelda.techspiress Javadoc讨论了何时应该使用或不应该使用该方法。请注意最后一部分:此方法不是很有用,将来可能会弃用。尽管我有点惊讶,但没有提到一致性是一个因素,ImmutableSet.of()例如与一样。编辑:这可能不是因素,因为不需要所有重载。
shmosel

1
嘿,感谢您提供@shmosel的参考资料,但我一直在寻找经验知识。对于使用过番石榴的人,为什么选择番石榴而不是HashSet?
Nelda.techspiress

27

使用Java 8可以使用流:

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

10
您是否检查过性能损失?这将执行一个iterable + iterator,一个新的HashSet(),然后为每个列表项在新集合上调用addAll()。总体而言,创建5个对象,就像创建一个新的HashSet(list)一样简单。
Agoston Horvath

1
@AgostonHorvath谢谢您的评论。我最初来这里时是在寻找这些信息。
TheRealChx101 '19

17
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年

8

在转换为set之前,我将执行Null检查。

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

3
Set<Foo> foo = myList == null ? Collections.emptySet() : new HashSet<Foo>(myList);
vegemite4me 2014年

6

您可以转换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);
}

我认为您的意思是将其从列表投射到集合。
西蒙

6

对于Java 8,这非常简单:

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

将使用“真实” Java 8 new ArrayList<>();-)
JR

6

Java - addAll

set.addAll(aList);

Java的 - 新对象

new HashSet(list)

Java-8

list.stream().collect(Collectors.toSet());

使用Guva

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);

5

我们不要忘记我们相对较新的朋友, 流API。如果您需要在将列表转换为集合之前进行预处理,则最好具有以下内容:

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


3

有多种获取Setas的方法:

    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。如果要获取a,HashSet则可以使用其他方法获取集合(选中set3)。


3

使用Java 10,您现在Set#copyOf可以轻松地将a转换List<E>为不可修改的Set<E>

例:

var set = Set.copyOf(list);

请记住,这是一个无序的操作,和null元素不是允许的,因为它会抛出NullPointerException

如果您希望它是可修改的,则只需将其传递给构造函数一个Set实现。



2

如果您使用Eclipse Collections

MutableSet<Integer> mSet = Lists.mutable.with(1, 2, 3).toSet();
MutableIntSet mIntSet = IntLists.mutable.with(1, 2, 3).toSet();

MutableSet接口扩展java.util.Set,而MutableIntSet接口则没有。您也可以使用工厂类将任何内容转换Iterable为。SetSets

Set<Integer> set = Sets.mutable.withAll(List.of(1, 2, 3));

有在Eclipse类别提供的可变工厂的更多解释在这里

如果ImmutableSet要从中获取List,则可以Sets按以下方式使用工厂:

ImmutableSet<Integer> immutableSet = Sets.immutable.withAll(List.of(1, 2, 3))

注意:我是Eclipse Collections的提交者


0

请记住,从List转换为Set将删除集合中的重复项,因为List支持重复项,但Set不支持Java中的重复项。

直接转换:将列表转换为集合的最常见,最简单的方法

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Converting a list to set
Set<String> set = new HashSet<>(list);

Apache Commons Collections:您还可以使用Commons Collections API将列表转换为Set:

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Creating a set with the same number of members in the list 
Set<String> set = new HashSet<>(4);

// Adds all of the elements in the list to the target set
CollectionUtils.addAll(set, list);

使用Stream:另一种方法是将给定列表转换为stream,然后将stream转换为set:-

// Creating a list of strings 
List<String> list = Arrays.asList("One", "Two", "Three", "Four"); 

// Converting to set using stream 
Set<String> set = list.stream().collect(Collectors.toSet()); 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.