jdk1.5 merge lists - Come faccio a unire due elenchi in Java?





14 Answers

In Java 8:

List<String> newList = Stream.concat(listOne.stream(), listTwo.stream())
                             .collect(Collectors.toList());
without duplicates collections

Condizioni: non modificare gli elenchi originali; Solo JDK, nessuna libreria esterna. Punti bonus per una versione monolinea o JDK 1.3.

C'è un modo più semplice di:

List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);



Probabilmente non più semplice, ma intrigante e brutto:

List<String> newList = new ArrayList<String>() { { addAll(listOne); addAll(listTwo); } };

Non usarlo nel codice di produzione ...;)




Non più semplice, ma senza ridimensionare il sovraccarico:

List<String> newList = new ArrayList<>(listOne.size() + listTwo.size());
newList.addAll(listOne);
newList.addAll(listTwo);



Un altro liner con Java 8:

List<String> newList = Stream.of(listOne, listTwo)
                             .flatMap(x -> x.stream())
                             .collect(Collectors.toList());

Come bonus, dato che Stream.of() è variadico, puoi concatenare tutte le liste che vuoi.

List<String> newList = Stream.of(listOne, listTwo, listThree)
                             .flatMap(x -> x.stream())
                             .collect(Collectors.toList());



Questo è semplice e solo una riga, ma aggiungerà il contenuto di listTwo a listOne. Hai davvero bisogno di mettere i contenuti in una terza lista?

Collections.addAll(listOne, listTwo.toArray());



Un po 'più breve sarebbe:

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);



Puoi fare un oneliner se la lista di destinazione è predeterminata.

(newList = new ArrayList<String>(list1)).addAll(list2);



In Java 8 (l'altro modo):

List<?> newList = 
Stream.of(list1, list2).flatMap(List::stream).collect(Collectors.toList());



Versione Java 8 con supporto per l'unione per chiave oggetto:

public List<SomeClass> mergeLists(final List<SomeClass> left, final List<SomeClass> right, String primaryKey) {
    final Map<Object, SomeClass> mergedList = new LinkedHashMap<>();

    Stream.concat(left.stream(), right.stream())
        .map(someObject -> new Pair<Object, SomeClass>(someObject.getSomeKey(), someObject))
        .forEach(pair-> mergedList.put(pair.getKey(), pair.getValue()));

    return new ArrayList<>(mergedList.values());
}



È possibile creare il proprio metodo di utilità Java 8 generico per concatenare un numero qualsiasi di elenchi .

@SafeVarargs
public static <T> List<T> concat(List<T>... lists) {
    return Stream.of(lists).flatMap(List::stream).collect(Collectors.toList());
}



Utilizzare una classe di supporto.

Suggerisco:

public static <E> Collection<E> addAll(Collection<E> dest, Collection<? extends E>... src) {
    for(Collection<? extends E> c : src) {
        dest.addAll(c);
    }

    return dest;
}

public static void main(String[] args) {
    System.out.println(addAll(new ArrayList<Object>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));

    // does not compile
    // System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList("a", "b", "c")));

    System.out.println(addAll(new ArrayList<Integer>(), Arrays.asList(1,2,3), Arrays.asList(4, 5, 6)));
}



Non c'è niente vicino a one-liner, ma penso che sia il più semplice:

List<String> newList = new ArrayList<String>(l1);
newList.addAll(l2);

for(String w:newList)
        System.out.printf("%s ", w);



Se vuoi farlo staticamente puoi fare quanto segue.

Gli esempi utilizzano 2 EnumSet in ordine naturale (== Enum-order) A, B e join quindi in un elenco ALL .

public static final EnumSet<MyType> CATEGORY_A = EnumSet.of(A_1, A_2);
public static final EnumSet<MyType> CATEGORY_B = EnumSet.of(B_1, B_2, B_3);

public static final List<MyType> ALL = 
              Collections.unmodifiableList(
                  new ArrayList<MyType>(CATEGORY_A.size() + CATEGORY_B.size())
                  {{
                      addAll(CATEGORY_A);
                      addAll(CATEGORY_B);
                  }}
              );



Non riesco a migliorare il two-liner nel caso generale senza introdurre il tuo metodo di utilità, ma se hai elenchi di stringhe e sei disposto ad assumere che le stringhe non contengano virgole, puoi tirare questo lungo -liner:

List<String> newList = new ArrayList<String>(Arrays.asList((listOne.toString().subString(1, listOne.length() - 1) + ", " + listTwo.toString().subString(1, listTwo.length() - 1)).split(", ")));

Se si rilasciano i generici, questo dovrebbe essere compatibile con JDK 1.4 (sebbene non l'abbia provato). Inoltre non raccomandato per il codice di produzione ;-)




Related