Partitionieren Sie eine Liste in Java

1. Übersicht

In diesem Tutorial werde ich veranschaulichen, wie eine Liste in mehrere Unterlisten einer bestimmten Größe aufgeteilt wird.

Für eine relativ einfache Operation gibt es überraschenderweise keine Unterstützung in den Standard-Java-Erfassungs-APIs. Glücklicherweise haben sowohl Guava als auch die Apache Commons-Sammlungen die Operation auf ähnliche Weise implementiert.

Dieser Artikel ist Teil der Reihe „ Java - Back to Basic “ hier auf Baeldung.

2. Partitionieren Sie die Liste mit Guave

Guava erleichtert das Partitionieren der Liste in Unterlisten einer bestimmten Größe - über die Operation Lists.partition :

@Test public void givenList_whenParitioningIntoNSublists_thenCorrect() { List intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List
    
      subSets = Lists.partition(intList, 3); List lastPartition = subSets.get(2); List expectedLastPartition = Lists. newArrayList(7, 8); assertThat(subSets.size(), equalTo(3)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
    

3. Partitionieren Sie eine Sammlung mit Guave

Das Partitionieren einer Sammlung ist auch mit Guava möglich:

@Test public void givenCollection_whenParitioningIntoNSublists_thenCorrect() { Collection intCollection = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); Iterable
    
      subSets = Iterables.partition(intCollection, 3); List firstPartition = subSets.iterator().next(); List expectedLastPartition = Lists. newArrayList(1, 2, 3); assertThat(firstPartition, equalTo(expectedLastPartition)); }
    

Beachten Sie, dass es sich bei den Partitionen um Unterlistenansichten der ursprünglichen Sammlung handelt. Dies bedeutet, dass Änderungen in der ursprünglichen Sammlung in den Partitionen berücksichtigt werden :

@Test public void givenListPartitioned_whenOriginalListIsModified_thenPartitionsChangeAsWell() { // Given List intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List
    
      subSets = Lists.partition(intList, 3); // When intList.add(9); // Then List lastPartition = subSets.get(2); List expectedLastPartition = Lists. newArrayList(7, 8, 9); assertThat(lastPartition, equalTo(expectedLastPartition)); }
    

4. Verwenden Sie Apache Commons Collections, um die Liste zu partitionieren

In den neuesten Versionen von Apache Commons Collections wurde kürzlich auch die Partitionierung einer Liste unterstützt:

@Test public void givenList_whenParitioningIntoNSublists_thenCorrect() { List intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List
    
      subSets = ListUtils.partition(intList, 3); List lastPartition = subSets.get(2); List expectedLastPartition = Lists. newArrayList(7, 8); assertThat(subSets.size(), equalTo(3)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
    

Es gibt keine entsprechende Option zum Partitionieren einer unformatierten Sammlung - ähnlich der Guava Iterables.partition in Commons-Sammlungen.

Schließlich gilt auch hier der gleiche Vorbehalt: Die resultierende Partition sind Ansichten der ursprünglichen Liste.

5. Partitionieren Sie die Liste mit Java8

Lassen Sie uns nun sehen, wie Sie Java8 zum Partitionieren unserer Liste verwenden.

5.1. Collectors partitioningBy

Wir können Collectors.partitioningBy () verwenden , um die Liste in zwei Unterlisten aufzuteilen - wie folgt:

@Test public void givenList_whenParitioningIntoSublistsUsingPartitionBy_thenCorrect() { List intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); Map
    
      groups = intList.stream().collect(Collectors.partitioningBy(s -> s > 6)); List
     
       subSets = new ArrayList
      
       (groups.values()); List lastPartition = subSets.get(1); List expectedLastPartition = Lists. newArrayList(7, 8); assertThat(subSets.size(), equalTo(2)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
      
     
    

Hinweis: Die resultierenden Partitionen sind keine Ansicht der Hauptliste, sodass Änderungen an der Hauptliste keine Auswirkungen auf die Partitionen haben.

5.2. Sammler groupingBy

Wir können Collectors.groupingBy () auch verwenden , um unsere Liste auf mehrere Partitionen aufzuteilen:

@Test public final void givenList_whenParitioningIntoNSublistsUsingGroupingBy_thenCorrect() { List intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); Map
    
      groups = intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3)); List
     
       subSets = new ArrayList
      
       (groups.values()); List lastPartition = subSets.get(2); List expectedLastPartition = Lists. newArrayList(7, 8); assertThat(subSets.size(), equalTo(3)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
      
     
    

Hinweis: Genau wie Collectors.partitioningBy () werden die resultierenden Partitionen nicht von Änderungen in der Hauptliste beeinflusst.

5.3. Teilen Sie die Liste nach Trennzeichen

Wir können auch Java8 verwenden, um unsere Liste nach Trennzeichen aufzuteilen:

@Test public void givenList_whenSplittingBySeparator_thenCorrect() { List intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8); int[] indexes = Stream.of(IntStream.of(-1), IntStream.range(0, intList.size()) .filter(i -> intList.get(i) == 0), IntStream.of(intList.size())) .flatMapToInt(s -> s).toArray(); List
    
      subSets = IntStream.range(0, indexes.length - 1) .mapToObj(i -> intList.subList(indexes[i] + 1, indexes[i + 1])) .collect(Collectors.toList()); List lastPartition = subSets.get(2); List expectedLastPartition = Lists. newArrayList(7, 8); assertThat(subSets.size(), equalTo(3)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
    

Hinweis: Wir haben "0" als Trennzeichen verwendet. Wir haben zuerst die Indizes aller "0" -Elemente in der Liste erhalten und dann die Liste auf diese Indizes aufgeteilt.

6. Fazit

Die hier vorgestellten Lösungen verwenden zusätzliche Bibliotheken - Guava oder die Apache Commons Collections-Bibliothek. Beide sind sehr leicht und insgesamt äußerst nützlich, daher ist es absolut sinnvoll, einen von ihnen auf dem Klassenpfad zu haben. Wenn dies jedoch keine Option ist, wird hier eine Nur-Java-Lösung angezeigt.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie auf GitHub - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.