La manière la plus concise de convertir un Set <T> en List <T>

201

Par exemple, je fais actuellement ceci:

Set<String> setOfTopicAuthors = ....

List<String> list = Arrays.asList( 
    setOfTopicAuthors.toArray( new String[0] ) );

Pouvez-vous battre cela?

Jacques René Mesrine
la source
2
Utilisation java.util.Collection: O (0)
Tim
@Carl, je dois soumettre l'ensemble dans une interface tierce qui nécessite une liste. @Tim Je souhaite pouvoir changer l'interface tierce pour utiliser Collection.
Jacques René Mesrine
1
Je vois; à moins de contraintes étranges, j'irais avec la réponse de Roger. Cependant, à moins que vous n'utilisiez à nouveau la liste, je ne l'attribuerai à rien (c'est-à-dire, utilisez foo.api (new ArrayList <String> (listOfTopicAuthors)) au lieu de foo.api (list)).
Carl
2
@ JacquesRenéMesrine: La première ligne de code en question est trompeuse: Prévue: Set<String> setOfTopicAuthors = ....Set<String> listOfTopicAuthors = ....
Réelle
Ou une autre façon de faire la même chose pourrait être List<String> list = Arrays.asList(setOfTopicAuthors.toArray(String[]::new)), détaillée dans la réponse liée.
Naman

Réponses:

432
List<String> list = new ArrayList<String>(listOfTopicAuthors);
Schildmeijer
la source
1
... et défiant ainsi radicalement les conventions du code Java: oracle.com/technetwork/java/javase/documentation/… ! :) :)
Håvard Geithus
après cela, lorsque j'ai essayé d'accéder à l'élément de liste, cela me donnait une erreur, "java.lang.ClassCastException: java.lang.Integer ne peut pas être converti en java.lang.String" ..don; je ne sais pas pourquoi ... c'est simple list.get (int) c'est ça ... une suggestion?
CoDe
2
Je crois qu'en Java 7 et au-dessus, vous pouvez omettre le paramètre type pour ArrayListdonner: List<String> l = new ArrayList<>(listOfTopicAuthors); Plus concis sans utiliser de bibliothèque externe?
Brett Duncavage du
Il lèvera NullPointerException au cas où il listOfTopicAuthorsserait nul.
w35l3y
91
List<String> l = new ArrayList<String>(listOfTopicAuthors);
Adamski
la source
4
pour avoir répondu dans la même minute que la réponse acceptée et ne pas avoir obtenu le crédit. +1
jayeffkay
@Adamski Je me retrouve avec une liste dont l'index commence à 1 au lieu de 0, un remède?
Jack
1
@Jack: Ce ne sera certainement pas le cas. À partir du Javadoc de java.util.List: "Les listes (comme les tableaux Java) sont basées sur zéro."
Adamski
@Adamski Merci pour la réponse. Je sais que les listes devraient être et sont basées sur zéro, c'est pourquoi cela m'est si étrange. Après avoir converti mon ensemble en liste, je ne peux effectuer aucune opération itérative dessus pour chaque tri, tri, etc. l'index commence à 1. Cependant, si je crée juste une liste normale, l'index commence à 0. Bizarre?
Jack
1
@Jack: Cela semble très bizarre. Si vous postez votre code en tant que question distincte, je suis sûr que quelqu'un pourra vous aider.
Adamski
23

Étant donné que nous avons, Set<String> stringSetnous pouvons utiliser les éléments suivants:

Java 10 (liste non modifiable)

List<String> strList = stringSet.stream().collect(Collectors.toUnmodifiableList());

Java 8 (listes modifiables)

import static java.util.stream.Collectors.*;
List<String> stringList1 = stringSet.stream().collect(toList());

Selon le doc de la méthodetoList()

Il n'y a aucune garantie sur le type, la mutabilité, la sérialisation ou la sécurité des threads de la liste retournée; si davantage de contrôle sur la liste retournée est nécessaire, utilisez toCollection (fournisseur).

Donc, si nous avons besoin d'une implémentation spécifique, par exemple, ArrayListnous pouvons l'obtenir de cette façon:

List<String> stringList2 = stringSet.stream().
                              collect(toCollection(ArrayList::new));

Java 8 (listes non modifiables)

Nous pouvons utiliser la Collections::unmodifiableListméthode et encapsuler la liste renvoyée dans les exemples précédents. Nous pouvons également écrire notre propre méthode personnalisée comme:

class ImmutableCollector {
    public static <T> Collector<T, List<T>, List<T>> toImmutableList(Supplier<List<T>> supplier) {
            return Collector.of( supplier, List::add, (left, right) -> {
                        left.addAll(right);
                        return left;
                    }, Collections::unmodifiableList);
        }
}

Et puis utilisez-le comme:

List<String> stringList3 = stringSet.stream()
             .collect(ImmutableCollector.toImmutableList(ArrayList::new)); 

Une autre possibilité est d'utiliser une collectingAndThenméthode qui permet d'effectuer une transformation finale avant de retourner le résultat:

    List<String> stringList4 = stringSet.stream().collect(collectingAndThen(
      toCollection(ArrayList::new),Collections::unmodifiableList));

Un point à noter est que la méthode Collections::unmodifiableListretourne une vue non modifiable de la liste spécifiée, selon la doc . Une collection de vues non modifiables est une collection non modifiable et est également une vue sur une collection de supports. Notez que des modifications de la collection de supports peuvent toujours être possibles et si elles se produisent, elles sont visibles à travers la vue non modifiable. Mais la méthode du collecteur Collectors.unmodifiableListrenvoie une liste vraiment immuable dans Java 10 .

akhil_mittal
la source
J'ai utilisé ceci pour convertir un Set<Double>en un List<Double, où l'ensemble provenait de LinkedHashMapla .keySet()méthode d'un. Eclipse m'a dit qu'il y avait une incompatibilité de type et que je ne pouvais pas convertir de Objectà List<Double>. Pourriez-vous me dire pourquoi cela a pu se produire? Je l'ai contourné par le casting, mais je me demandais pourquoi cela se produisait.
Ungeheuer
1
Oui, puisque les développeurs Java devraient utiliser de plus en plus de fonctionnalités Java 8, cette réponse est meilleure que les 2 réponses ci-dessus.
Shubham Pandey
13

Essayez ceci pour Set :

Set<String> listOfTopicAuthors = .....
List<String> setList = new ArrayList<String>(listOfTopicAuthors); 

Essayez ceci pour la carte :

Map<String, String> listOfTopicAuthors = .....
// List of values:
List<String> mapValueList = new ArrayList<String>(listOfTopicAuthors.values());
// List of keys:
List<String> mapKeyList = new ArrayList<String>(listOfTopicAuthors.KeySet());
Prabhakar Manthena
la source
2

Si vous utilisez Guava, vous importez statiquement la newArrayListméthode de la classe Lists :

List<String> l = newArrayList(setOfAuthors);
Andrejs
la source
0

pas vraiment sûr de ce que vous faites exactement via le contexte de votre code mais ...

pourquoi faire la listOfTopicAuthorsvariable du tout?

List<String> list = Arrays.asList((....).toArray( new String[0] ) );

le "...." représente la manière dont votre jeu est entré en jeu, qu'il soit nouveau ou qu'il provienne d'un autre endroit.

jp093121
la source