2009-09-15 2 views

ответ

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

Это вызовет исключение NullPointerException, если список пуст. – Ashish

+87

@Ashish: Это совершенно не относится к вопросу. Никто не спрашивал, как преобразовать null в Set. Люди, всегда требующие обработки null, являются признаком того, насколько нарушена Java (культура). Почти всегда значение null является ошибкой. ЧЕРЕЗ ИСКЛЮЧЕНИЕ ИСКЛЮЧИТЕЛЬНО ЛУЧШЕЕ, ЧТО ВЫ МОЖЕТЕ СДЕЛАТЬ. Особенно, когда это пустая ссылка на Сборник: как часто вы можете представить семантическое значение нулевой ссылки на коллекцию - и чтобы значение отличалось от пустой коллекции? –

+2

Согласны, а не null, вы должны (почти) всегда передавать: неизменные статические пустые экземпляры ваших beans или Collections.emptyXXX() для ваших коллекций. Это также делает ваш код намного легче читать, если он не загрязнен нулевыми проверками в начале каждого метода. –

112

Я согласен с sepp2k, но есть некоторые другие детали, которые могут имеют значение:

new HashSet<Foo>(myList); 

даст вам несортированный набор, который не имеет дубликатов. В этом случае дублирование идентифицируется с использованием метода .equals() для ваших объектов. Это выполняется в сочетании с методом .hashCode(). (Более подробно о равенстве смотрите here)

Альтернатива, которая дает упорядоченный набор является:

new TreeSet<Foo>(myList); 

Это работает, если Foo реализует Сопоставимые. Если это не то вы можете использовать компаратор:

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

+1

Почему ImmutableSet.copyOf лучше? – user672009

+1

Какие преимущества имеет newHashSet() у Guava над базовым java new HashSet()? –

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

9

Я бы выполнить Null проверку перед преобразованием устанавливать ,

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

Или 'Set foo = myList == null? Collections.emptySet(): new HashSet (myList); ' – vegemite4me

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

Я думаю, вы хотели отбросить его из списка в Set. – Simon

17

Использование Java 8 вы можете использовать поток:

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

Вы проверили штраф за это? это сделает итеративный + итератор, новый HashSet(), а затем для каждого элемента списка - вызов addAll() в новом наборе. В целом, приблизительно. 5 объектов, созданных для чего-то простого, как новый HashSet (список). –

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. Если вам нужно список Preprocess перед преобразованием его в набор, то лучше иметь что-то вроде:

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

Более Java 8 упругое решение с Optional.ofNullable

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

С Java 10, вы могли бы прямо сейчас использовать Set#copyOf легко преобразовать List<E> к неизменяемо Set<E>:

Пример:

var set = Set.copyOf(list); 

Имейте в виду, что это неупорядоченный операция, и null элементы не допускается, так как это будет бросать NullPointerException.

Если вы хотите, чтобы он был модифицируемым, просто передайте его в конструктор Set.

Смежные вопросы