Einfachste Möglichkeit, eine Liste in ein Set in Java zu konvertieren


628

Was ist der einfachste Weg, um Lista Setin Java zu konvertieren ?

Antworten:


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

3
Obwohl diese Antwort richtig ist, fehlt ein ausreichender technischer Kontext, um die beste / akzeptierte Antwort zu gewährleisten, da hier Fallstricke auftreten, je nachdem, welche Implementierungen von Setund welche Mapverwendet werden. HashSetwird hier angenommen .
Madbreaks

145

Ich stimme sepp2k zu, aber es gibt noch einige andere Details, die wichtig sein könnten:

new HashSet<Foo>(myList);

Sie erhalten ein unsortiertes Set ohne Duplikate. In diesem Fall wird die Duplizierung mit der Methode .equals () für Ihre Objekte identifiziert. Dies erfolgt in Kombination mit der Methode .hashCode (). (Weitere Informationen zur Gleichstellung finden Sie hier )

Eine Alternative, die eine sortierte Menge ergibt, ist:

new TreeSet<Foo>(myList);

Dies funktioniert, wenn Foo Comparable implementiert. Wenn dies nicht der Fall ist, möchten Sie möglicherweise einen Komparator verwenden:

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

Dies hängt entweder von compareTo () (von der vergleichbaren Schnittstelle) oder compare () (vom Komparator) ab, um die Eindeutigkeit sicherzustellen. Wenn Sie sich also nur für die Einzigartigkeit interessieren, verwenden Sie das HashSet. Wenn Sie nach dem Sortieren sind, ziehen Sie das TreeSet in Betracht. (Denken Sie daran: Später optimieren!) Wenn Zeiteffizienz wichtig ist, verwenden Sie ein HashSet, wenn Raumeffizienz wichtig ist, schauen Sie sich TreeSet an. Beachten Sie, dass effizientere Implementierungen von Set und Map über Trove (und andere Standorte) verfügbar sind.


Vielen Dank für den benutzerdefinierten Comparator-Anwendungsfall!
Justin Papez

70

Wenn Sie die Guava- Bibliothek verwenden:

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

oder besser:

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

2
Warum ist ImmutableSet.copyOf besser?
user672009

1
Welche Vorteile hat Guavas newHashSet () gegenüber dem grundlegenden Java-HashSet ()?
Nelda.techspiress

@ Nelda.techspiress Der Javadoc diskutiert, wann die Methode angewendet werden soll oder nicht. Beachten Sie den letzten Teil: Diese Methode ist nicht sehr nützlich und wird wahrscheinlich in Zukunft veraltet sein. Obwohl ich ein bisschen überrascht bin, wird Konsistenz nicht als Faktor erwähnt, wie es ImmutableSet.of()zum Beispiel bei ist. BEARBEITEN: Dies ist möglicherweise kein Faktor, da alle Überlastungen nicht benötigt werden.
Shmosel

1
Hey, danke für die Referenz @shmosel, aber ich habe mehr nach empirischem Wissen gesucht. Warum sollte Guava für diejenigen, die Guava verwendet haben, HashSet vorgezogen werden?
Nelda.techspiress

27

Mit Java 8 können Sie Stream verwenden:

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

10
Haben Sie die Leistungsstrafe überprüft? Dies würde einen iterierbaren + Iterator, ein neues HashSet () und dann für jedes Listenelement einen addAll () -Aufruf für das neue Set ausführen. Insgesamt cca. 5 Objekte, die für etwas so Einfaches wie ein neues HashSet (Liste) erstellt wurden.
Agoston Horvath

1
@AgostonHorvath Vielen Dank für Ihren Kommentar. Ich habe ursprünglich nach diesen Informationen gesucht, als ich hierher kam.
TheRealChx101

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

oder vollständiges Beispiel

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 für ein vollständiges Codebeispiel. Ein zusätzlicher Hinweis hier ist, dass das Hashing nicht garantiert von Lauf zu Lauf gleich ist. Das bedeutet, dass die Liste, die nach 'Set values ​​.....' gedruckt wird, in einem Lauf 'ABC' und in einem anderen Lauf 'CBA' sein kann. Wie ich in meiner Antwort erwähnt habe, können Sie ein Baumset verwenden, um eine stabile Reihenfolge zu erhalten. Eine andere Option wäre die Verwendung eines LinkedHashSet, das sich an die Reihenfolge erinnert, in der Elemente hinzugefügt wurden.
Spina

8

Ich würde eine Nullprüfung durchführen, bevor ich zu set konvertiere.

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

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

6

Sie können konvertieren List<>zuSet<>

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);
}

Ich denke, Sie wollten es von List zu Set übertragen.
Simon

6

Für Java 8 ist es sehr einfach:

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

"Echtes" Java 8 wäre zu verwenden new ArrayList<>();-)
JR

6

Java - addAll

set.addAll(aList);

Java - neues Objekt

new HashSet(list)

Java-8

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

Mit Guva

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);

5

Vergessen wir nicht unseren relativ neuen Freund, Stream-API. Wenn Sie eine Liste vorverarbeiten müssen, bevor Sie sie in einen Satz konvertieren, ist es besser, Folgendes zu haben:

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

4

Der beste Weg, um Konstruktor zu verwenden

Set s= new HashSet(list);

In Java 8 können Sie auch stream api :: verwenden

Set s= list.stream().collect(Collectors.toSet());

3

Es gibt verschiedene Möglichkeiten, ein As zu erhalten 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);

Wenn wir es verwenden Collectors.toSet(), wird ein Satz zurückgegeben und gemäß dem Dokument : There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. Wenn wir ein bekommen wollen, HashSetkönnen wir die andere Alternative verwenden, um ein Set zu bekommen (check set3).


3

Mit Java 10 können Sie jetzt Set#copyOfeinfach a List<E>in ein nicht modifizierbares konvertieren Set<E>:

Beispiel:

var set = Set.copyOf(list);

Beachten Sie, dass dies eine ungeordnete Operation ist und nullElemente nicht zulässig sind, da sie a auslösen NullPointerException.

Wenn Sie möchten, dass es geändert werden kann, übergeben Sie einfach eine SetImplementierung an den Konstruktor .


2

Eine stabilere Java 8-Lösung mit Optional.ofNullable

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

2

Wenn Sie Eclipse-Sammlungen verwenden :

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

Die MutableSetSchnittstelle wird erweitert, java.util.Setdie MutableIntSetSchnittstelle jedoch nicht. Sie können auch alle mithilfe der Factory-Klasse Iterablein a konvertieren .SetSets

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

Weitere Erläuterungen zu den veränderlichen Fabriken in Eclipse Collections finden Sie hier .

Wenn Sie eine ImmutableSetvon a möchten List, können Sie die SetsFabrik wie folgt verwenden:

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

Hinweis: Ich bin ein Committer für Eclipse-Sammlungen


0

Denken Sie daran, dass beim Konvertieren von List zu Set Duplikate aus der Sammlung entfernt werden, da List Duplikate unterstützt, Set jedoch keine Duplikate in Java unterstützt.

Direkte Konvertierung: Die häufigste und einfachste Methode zum Konvertieren einer Liste in einen Satz

// 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: Sie können auch die Commons Collections-API verwenden, um eine Liste in einen Satz zu konvertieren: -

// 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);

Verwenden von Stream: Eine andere Möglichkeit besteht darin, eine bestimmte Liste in einen Stream zu konvertieren und dann in einen Set zu streamen: -

// 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()); 
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.