web-dev-qa-db-fra.com

Convertir un ensemble en liste sans créer de nouvelle liste

J'utilise ce code pour convertir un Set en un List:

Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //returns different result each time
  List listOfNames = new ArrayList(set);
  mainMap.put(differentKeyName,listOfNames);
}

Je veux éviter de créer une nouvelle liste à chaque itération de la boucle. Est-ce possible?

458

Vous pouvez utiliser la méthode List.addAll () . Il accepte une collection en tant qu'argument et votre ensemble est une collection.

List<String> mainList = new ArrayList<String>();
mainList.addAll(set);

EDIT: pour répondre à la modification de la question.
Il est facile de voir que si vous voulez avoir une valeur Map avec Lists, vous devez créer k différentes listes pour avoir k valeurs différentes.
Ainsi: Vous ne pouvez pas du tout éviter de créer ces listes, il vous faudra les créer.

Contournement possible:
Déclarez votre Map comme un Map<String,Set> ou Map<String,Collection> et insérez simplement votre jeu.

753
amit

Utilisez le constructeur pour le convertir:

List<?> list = new ArrayList<?>(set);
398
zengsn

Également dans la bibliothèque Guava Collect, vous pouvez utiliser newArrayList(Collection):

Lists.newArrayList([your_set])

Ce serait très similaire à la réponse précédente de amit, sauf que vous n'avez pas besoin de déclarer (ou instancier) aucun objet list.

80
chaiyachaiya

Nous pouvons utiliser le lignage suivant dans Java 8:

List<String> list = set.stream().collect(Collectors.toList());

Voici un petit exemple:

public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("A");
        set.add("B");
        set.add("C");
        List<String> list = set.stream().collect(Collectors.toList());
}
37
rajadilipkolli

la solution la plus simple

Je voulais un moyen très rapide de convertir mon ensemble en liste et de le renvoyer.

 return new ArrayList<Long>(mySetVariable);
20
Basheer AL-MOMANI

Vous pouvez utiliser ce changement d'une ligne: Arrays.asList(set.toArray(new Object[set.size()]))

Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); 
  mainMap.put(differentKeyName, Arrays.asList(set.toArray(new Object[set.size()])));
}  
6
Saheed

Je ferais :

Map<String, Collection> mainMap = new HashMap<String, Collection>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName,set);
}
4
Jerome L

Java 8 offre la possibilité d’utiliser des flux et vous pouvez obtenir une liste de Set<String> setString sous la forme:

List<String> stringList = setString.stream().collect(Collectors.toList());

Bien que l'implémentation interne fournisse une instance de ArrayList:

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

mais JDK ne le garantit pas. Comme mentionné ici :

Il n'y a aucune garantie sur le type, la mutabilité, la sérialisabilité ou la sécurité des threads de la liste renvoyée. si vous avez besoin de plus de contrôle sur la liste renvoyée, utilisez toCollection (Supplier).

Si vous voulez être sûr de toujours, vous pouvez demander une instance spécifique comme:

List<String> stringArrayList = setString.stream()
                     .collect(Collectors.toCollection(ArrayList::new));
3
i_am_zero

Récemment j'ai trouvé ceci:

ArrayList<T> yourList = Collections.list(Collections.enumeration(yourSet<T>));
2
Stand Yang

Je crée une méthode simple static:

public static <U> List<U> convertSetToList(Set<U> set)
{
    return new ArrayList<U>(set);
}

... ou si vous voulez définir le type de liste, vous pouvez utiliser:

public static <U, L extends List<U>> List<U> convertSetToList(Set<U> set, Class<L> clazz) throws InstantiationException, IllegalAccessException
{
    L list = clazz.newInstance();
    list.addAll(set);
    return list;
}
2
thomas.adamjak

J'ai trouvé cela très utile et utile pour créer une liste à partir d'un ensemble.

ArrayList < String > L1 = new ArrayList < String > ();
L1.addAll(ActualMap.keySet());
for (String x: L1) {
    System.out.println(x.toString());
}
1
Karthic.K

Par souci d'exhaustivité ...

Dites que vous voulez vraiment traiter les valeurs de la carte comme des listes, tout en évitant de copier le jeu dans une liste à chaque fois.

Par exemple, vous appelez peut-être une fonction de la bibliothèque qui crée un ensemble, mais vous transmettez votre résultat Map <String, List> à une fonction de bibliothèque (mal conçue, mais hors de votre portée) qui prend uniquement Map <String, List>. , même si vous savez que les opérations effectuées avec les listes sont également applicables à toute collection (et donc à tout ensemble). Et pour une raison quelconque , vous devez éviter la surcharge de temps/mémoire liée à la copie de chaque ensemble dans une liste.

Dans ce cas de super niche, en fonction du comportement (peut-être inconnaissable) de la fonction de bibliothèque dont vous avez besoin, vous pourrez peut-être créer une vue Liste sur chaque ensemble. Notez que cela est intrinsèquement dangereux (car les exigences de la fonction de bibliothèque de chaque liste pourraient probablement changer sans que vous le sachiez), une autre solution devrait donc être privilégiée. Mais voici comment vous le feriez.

Vous créez une classe qui implémente l'interface List, prend un Set dans le constructeur et l'affecte à un champ, puis utilise ce Set interne pour implémenter l'API List (dans la mesure du possible et selon vos souhaits).

Notez que certains comportements de liste que vous ne pourrez tout simplement pas imiter sans stocker les éléments sous forme de liste, et certains comportements que vous ne pourrez imiter que partiellement. Encore une fois, cette classe n'est pas un substitut sûr pour Listes en général. En particulier, si vous savez que le cas d'utilisation nécessite des opérations liées à l'index ou à MUTTER la liste, cette approche ira très vite vers le sud.

public class ListViewOfSet<U> implements List<U> {
    private final Set<U> wrappedSet;
    public ListViewOfSet(Set<U> setToWrap) { this.wrappedSet = setToWrap; }

    @Override public int size() { return this.wrappedSet.size(); }
    @Override public boolean isEmpty() { return this.wrappedSet.isEmpty(); }
    @Override public boolean contains(Object o) { return this.wrappedSet.contains(o); }
    @Override public Java.util.Iterator<U> iterator() { return this.wrappedSet.iterator(); }
    @Override public Object[] toArray() { return this.wrappedSet.toArray(); }
    @Override public <T> T[] toArray(T[] ts) { return this.wrappedSet.toArray(ts); }
    @Override public boolean add(U e) { return this.wrappedSet.add(e); }
    @Override public boolean remove(Object o) { return this.wrappedSet.remove(o); }
    @Override public boolean containsAll(Collection<?> clctn) { return this.wrappedSet.containsAll(clctn); }
    @Override public boolean addAll(Collection<? extends U> clctn) { return this.wrappedSet.addAll(clctn); }
    @Override public boolean addAll(int i, Collection<? extends U> clctn) { throw new UnsupportedOperationException(); }
    @Override public boolean removeAll(Collection<?> clctn) { return this.wrappedSet.removeAll(clctn); }
    @Override public boolean retainAll(Collection<?> clctn) { return this.wrappedSet.retainAll(clctn); }
    @Override public void clear() { this.wrappedSet.clear(); }
    @Override public U get(int i) { throw new UnsupportedOperationException(); }
    @Override public U set(int i, U e) { throw new UnsupportedOperationException(); }
    @Override public void add(int i, U e) { throw new UnsupportedOperationException(); }
    @Override public U remove(int i) { throw new UnsupportedOperationException(); }
    @Override public int indexOf(Object o) { throw new UnsupportedOperationException(); }
    @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); }
    @Override public ListIterator<U> listIterator() { throw new UnsupportedOperationException(); }
    @Override public ListIterator<U> listIterator(int i) { throw new UnsupportedOperationException(); }
    @Override public List<U> subList(int i, int i1) { throw new UnsupportedOperationException(); }
}

...
Set set = getSet(...);
ListViewOfSet listOfNames = new ListViewOfSet(set);
...
0
Daniel Avery