web-dev-qa-db-pt.com

Converter conjunto para lista sem criar nova lista

Eu estou usando este código para converter um Set para um 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);
}

Eu quero evitar a criação de uma nova lista em cada iteração do loop. Isso é possível?

444
Muhammad Imran Tariq

Você pode usar o método List.addAll () . Aceita uma coleção como argumento e seu conjunto é uma coleção.

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

EDIT: como responder à edição da questão.
É fácil ver que se você quiser ter uma Map com Lists como valores, para ter k valores diferentes, você precisa criar k listas diferentes.
Assim: Você não pode evitar a criação dessas listas, as listas terão que ser criadas.

Possível trabalho em torno de:
Em vez disso, declare seu Map como Map<String,Set> ou Map<String,Collection> e insira o seu conjunto.

740
amit

Use o construtor para convertê-lo:

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

Também da biblioteca Guava Collect, você pode usar newArrayList(Collection):

Lists.newArrayList([your_set])

Isso seria muito semelhante à resposta anterior de amit , exceto que você não precisa declarar (ou instanciar) qualquer objeto list.

74
chaiyachaiya

Podemos usar seguindo um liner no Java 8:

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

Aqui está um pequeno exemplo:

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());
}
35
rajadilipkolli

a solução mais simples

Eu queria uma maneira muito rápida de converter o meu conjunto para List e devolvê-lo, então em uma linha eu fiz

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

Você poderia usar esta mudança de linha: 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

Eu faria :

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

O Java 8 fornece a opção de usar fluxos e você pode obter uma lista de Set<String> setString como:

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

Embora a implementação interna a partir de agora forneça uma instância 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);
    }

mas o JDK não garante isso. Como mencionado aqui :

Não há garantias sobre o tipo, a mutabilidade, a serialização ou a segurança de thread da Lista retornada; se for necessário mais controle sobre a Lista retornada, use toCollection (Supplier).

Caso você queira ter certeza, então você pode solicitar uma instância especificamente como:

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

Recentemente eu encontrei isto:

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

Eu crio o método simples static:

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

... ou se você quiser definir o tipo de lista, você pode usar:

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

Eu encontrei este trabalho bem e útil para criar uma lista de um conjunto.

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

Por uma questão de perfeição ...

Digamos que você realmente queira tratar os valores do Mapa como Listas, mas deseja evitar copiar o Conjunto para uma Lista a cada vez.

Por exemplo, talvez você esteja chamando uma função de biblioteca que cria um Set, mas está passando o resultado de Map <String, List> para uma função de biblioteca (mal projetada, mas fora de suas mãos) que só usa Map <String, List> , embora de alguma forma você saiba que as operações que ele faz com as Listas são igualmente aplicáveis ​​a qualquer Coleção (e, portanto, qualquer Conjunto). E por algum motivo você precisa evitar a sobrecarga de velocidade/memória de copiar cada conjunto para uma lista.

Neste super nicho, dependendo do comportamento (talvez incognoscível) que a função de biblioteca precisa de suas Listas, você pode ser capaz de criar uma Lista view sobre cada Conjunto. Observe que isso é intrinsecamente inseguro (porque os requisitos da função de biblioteca de cada Lista poderiam, presumivelmente, mudar sem você saber), portanto, outra solução deve ser preferida. Mas aqui está como você faria isso.

Você criaria uma classe que implementa a interface List, pega um Set no construtor e atribui esse Set a um campo e, em seguida, usa esse Set interno para implementar a List API (na medida do possível e desejada).

Note que alguns comportamentos da Lista que você simplesmente não será capaz de imitar sem armazenar os elementos como uma Lista, e algum comportamento que você apenas parcialmente poderá imitar. Novamente, esta classe não é um substituto seguro para as Listas Em geral, se você souber que o caso de uso requer operações relacionadas ao índice ou MUTATING the List, essa abordagem iria para o sul muito rapidamente.

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