2015-08-12 9 views
9

Ho 2 Liste:Come zip due Java Elenca

List<String> subjectArr = Arrays.asList<String>("aa", "bb", "cc"); 
List<Long> numArr = Arrays.asList<Long>(2L, 6L, 4L); 

Come posso creare nuovi List e zip due liste in esso?

List<?> subjectNumArr = zip(subjectArr, numArr); 
// subjectNumArr == [{'aa',2},{'bb',6},{'cc',4}] 
+4

Forse, una mappa dovrebbe essere più utile per la raccolta composita – vefthym

+0

sarà necessario creare un oggetto personalizzato che può essere utilizzato per creare tale elenco – Jabir

risposta

5

Uso un ArrayList di Map.Entry<String, Long>, controllando che entrambi ArrayLists hanno uguali dimensioni (come sembra essere il vostro requisito), così:

List<Map.Entry<String,Long>> subjectNumArr = new ArrayList<>(numArr.size()); 
if (subjectArr.size() == numArr.size()) { 
    for (int i = 0; i < subjectArr.size(); ++i) { 
     subjectNumArr.add(new AbstractMap.SimpleEntry<String, Long>(subjectArr.get(i), numArr.get(i)); 
    } 
} 

Questo è tutto il codice necessario!

Poi, per scorrere i risultati, usare qualcosa come:

for (Map.Entry<String, Long> entry : subjectNumArr) { 
    String key = entry.getKey(); 
    Long value = entry.getValue(); 
} 

o, si può ottenere semplicemente la coppia alla posizione i (tenendo ordine di inserimento), da:

Map.Entry<String, Long> entry = subjectNumArr.get(i); 

Questo può anche contenere voci duplicate, a differenza della soluzione Map che ho inizialmente suggerito, senza la necessità di definire la propria classe (Pair).

1

Sono d'accordo con vefthym se avete a che fare con la lista quindi creare una classe come qui sotto -:

class DirtyCoding{ 
    String subject; 
    int numbr; 
} 

Poi iterare la vostra lista, creare l'oggetto di DirtyCoding, popolano e aggiungere quindi aggiungerlo a List<DirtyCoding>.

-1

In Java 8: È possibile eseguire questa operazione in una riga utilizzando la classe Stream e Collector.

In Java 7/6/5:

List list = new ArrayList(); 

     if(subjectArr.size() == numArr.size()) 
     { 
      for (int i = 0; i < subjectArr.size(); i++) { // Loop through every subject/name 
       list.add(subjectArr.get(i) + " " + numArr.get(i)); // Concat the two, and add it 
      } 
     } 
+0

Come lo faresti in Java8? – slartidan

0

Si dovrebbe creare un ArrayList di listino: -

ArrayList<List> subjectNumArr = new ArrayList<>(); 
Iterator iter = subjectArr.iterator(); 
int count=0; 
while(iter.hasNext()){ 
subjectNumArr.add(Arrays.asList(iter.next(),numArr.get[count++]); 
} 
0

Le mie idee:

  • Definire una classe per le tue coppie. Questo rende il codice estendibile (ad esempio se si desidera aggiungere un terzo campo).
  • Definisci le tue liste con il metodo conveniente Arrays.asList. È di facile comprensione, breve e genera automaticamente raccolte generiche.
  • Utilizzare superclassi o interfacce come tipi variabili. Ho usato List nell'esempio, forse Collection sarebbe ancora meglio. Dichiarare le variabili come ArrayList solo se è necessario che l'elenco sia così specifico. Questo ti darà la possibilità di usare altre implementazioni, senza dover cambiare molto codice.

vorrei creare Pair oggetti come questo:

import java.util.*; 

class Pair { 
    String subject; 
    Long num; 
} 

public class Snippet { 

    public static void main(String[] args) { 
     List<String> subjectArr = Arrays.asList("aa", "bb", "cc"); 
     List<Long> numArr = Arrays.asList(2l,6l,4l); 

     // create result list 
     List<Pair> pairs = new ArrayList<>(); 

     // determine result size 
     int length = Math.min(subjectArr.size(), numArr.size()); 

     // create pairs 
     for (int position = 0; position < length; position++) { 
      Pair pair = new Pair(); 
      pair.subject = subjectArr.get(position); 
      pair.num = numArr.get(position); 
      pairs.add(pair); 
     } 
    } 
} 
3

L'operazione che si desidera è chiamato zipping.

Per prima cosa è necessaria una struttura dati che contenga due oggetti. Chiamiamolo Pair:

public final class Pair<A, B> { 
    private final A left; 
    private final B right; 

    public Pair(A left, B right) { 
    this.left = left; 
    this.right = right; 
    } 

    public A left() { return left; } 
    public B right() { return right; } 

    public String toString() { 
    return "{" + left + "," + right + "}"; 
    } 
} 

allora avete bisogno di implementare un metodo zip:

public static <A, B> List<Pair<A, B>> zip(List<A> as, List<B> bs) { 
    Iterator<A> it1 = as.iterator(); 
    Iterator<B> it2 = bs.iterator(); 
    List<Pair<A, B>> result = new ArrayList<>(); 
    while (it1.hasNext() && it2.hasNext()) { 
    result.add(new Pair<A, B>(it1.next(), it2.next())); 
    } 
    return result; 
} 

E infine l'utilizzo di zip:

zip(subjectArr, numArr); 
+1

Un metodo factory statico 'makePair (A left, B right)' invece del costruttore in Pair renderebbe possibile questa linea: 'result.add (Pair.makePair (it1.next(), it2.next()))) ; '(non c'è bisogno di ripetere i tipi) – slartidan

20

Ecco Java-8 soluzione utilizzando il Pair classe (come nella risposta @ZhekaKozlov):

public static <A, B> List<Pair<A, B>> zipJava8(List<A> as, List<B> bs) { 
    return IntStream.range(0, Math.min(as.size(), bs.size())) 
      .mapToObj(i -> new Pair<>(as.get(i), bs.get(i))) 
      .collect(Collectors.toList()); 
} 
0

Utilizzare una delle risposte da Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip) a zip e applicare una funzione contemporaneamente

esempio Utilizzando un flusso zip:

<A,B,C> Stream<C> zipped(List<A> lista, List<B> listb, BiFunction<A,B,C> zipper){ 
    int shortestLength = Math.min(lista.size(),listb.size()); 
    return IntStream.range(0,shortestLength).mapToObject(i -> { 
      return zipper.apply(lista.get(i), listb.get(i)); 
    });   
} 

per il quale si può anche utilizzare di Guava Streams.zip()

1

Come da related question, è possibile utilizzare Guava (> = 21,0) per fare questo:

List<String> subjectArr = Arrays.asList("aa", "bb", "cc"); 
List<Long> numArr = Arrays.asList(2L, 6L, 4L); 
List<Pair> pairs = Streams.zip(subjectArr.stream(), numArr.stream(), Pair::new) 
     .collect(Collectors.toList());