2017-11-04 5 views
2

Betrachten wir: List <String> ints = Arrays.asList("1","2","3","4","5","6") und lassen Sie k=2.Wie generiere ich alle k-Unterlisten einer Liste in Java?

Wir möchten folgende Liste zurückzukehren List<String> : ["12", "23", "34", "45", "56"]

Was elegante Lösungen? Ist es möglich, es mit Streams zu tun?

Natürlich kann es auf viele Arten gelöst werden, die einfachste ist über die gesamte Liste mit verschachtelten Liste 1...k iterieren.

Irgendwelche Ideen?

+2

Streams mit mehreren Elementen ist für den Zugriff auf simuntaniously nicht sehr elegant. Warum nicht iterieren? seine einfache, leicht zu verstehende und leicht zu debuggende – IEE1394

+0

ist d. h. "16" auch Unterliste? – dehasi

+2

Es ist möglich und jemand wird wahrscheinlich eine gewundene Lösung postulieren. Standard-Java-8-Streams sind dafür nicht geeignet, verwenden Sie sie nicht oder verwenden Sie eine bessere Stream-Bibliothek. – Oleg

Antwort

3

Mit Streams:

 final List<String> ints = Arrays.asList("1", "2", "3", "4", "5", "6"); 
     final int k = 2; 
     final List<String> result = IntStream.iterate(0, i -> i + 1).limit(ints.size() - k + 1) 
       .mapToObj(i -> ints.subList(i, i + k).stream().reduce("", (a, b) -> a + b + "")) 
       .collect(Collectors.toList()); 

     System.out.println(result);3 

Mit einer for-Schleife:

List<String> result = new LinkedList<>(); 
    for(int i = 0 ; i < ints.size() - k + 1; i++) { 
     StringBuilder sb = new StringBuilder(); 
     for(int j = 0; j < k; j++) { 
      sb.append(ints.get(i+j)); 
     } 
     result.add(sb.toString()); 
    } 

    System.out.println(result); 

sich nun entscheiden ;-)

3

Wenn Sie mit einem Collection<String> anstelle eines List<String> in Ihr Ergebnis leben , dann könnten Sie Java 9 Collectors.flatMapping verwenden:

Collection<String> result = IntStream.range(0, ints.size() - k) 
    .boxed() 
    .collect(Collectors.groupingBy(i -> i, 
     Collectors.flatMapping(i -> ints.subList(i, i + k).stream(), 
      Collectors.joining()))) 
    .values(); 

Ein anderer Weg, ähnlich wie IEE1394's answer:

List<String> result = IntStream.range(0, ints.size() - k) 
    .mapToObj(i -> String.join("", ints.subList(i, i + k))) 
    .collect(Collectors.toList()); 
+0

Ich mag das ziemlich viel .. ein bisschen schwer zu lesen, aber nett – Eugene

+0

Hallo @Eugene! Vielen Dank! Ich mag den zweiten, aber Sie wissen ... Ich denke, ich bevorzuge einen gemeinsamen imperativen Ansatz ... –

+0

Sie könnten das Ergebnis an 'new ArrayList <>()' -Konstruktor übergeben, um eine Liste zurück zu bekommen – Lino

Verwandte Themen