Opdel en liste i Java

1. Oversigt

I denne vejledning vil jeg illustrere hvordan man opdeler en liste i flere underlister af en given størrelse.

For en relativt enkel operation er der overraskende ingen understøttelse i standard Java-samling API'erne. Heldigvis har både Guava og Apache Commons Collections implementeret operationen på en lignende måde.

Denne artikel er en del af "Java - Tilbage til Basic”-Serien her på Baeldung.

2. Brug Guava til at opdele listen

Guava gør det lettere at opdele listen i underlister af en bestemt størrelse - via det Lister. Partition operation:

@Test offentligt ugyldigt givenList_whenParitioningIntoNSublists_thenCorrect () {List intList = Lists.newArrayList (1, 2, 3, 4, 5, 6, 7, 8); Liste subSets = Lists.partition (intList, 3); Liste lastPartition = subSets.get (2); Liste forventetLastPartition = Lister. newArrayList (7, 8); assertThat (subSets.size (), equalTo (3)); assertThat (lastPartition, equalTo (forventetLastPartition)); }

3. Brug Guava til at opdele en samling

Partitionering af en samling er også muligt med Guava:

@Test offentligt ugyldigt givetCollection_whenParitioningIntoNSublists_thenCorrect () {Collection intCollection = Lists.newArrayList (1, 2, 3, 4, 5, 6, 7, 8); Iterabel subSets = Iterables.partition (intCollection, 3); Liste firstPartition = subSets.iterator (). Næste (); Liste forventetLastPartition = Lister. newArrayList (1, 2, 3); assertThat (firstPartition, equalTo (forventetLastPartition)); }

Husk, at partitionerne er underliste visninger af den originale samling - hvilket betyder, at ændringer i den originale samling afspejles i partitionerne:

@Test offentlig ugyldighed givenListPartitioned_whenOriginalListIsModified_thenPartitionsChangeAsWell () {// given liste intList = Lists.newArrayList (1, 2, 3, 4, 5, 6, 7, 8); Liste subSets = Lists.partition (intList, 3); // Når intList.add (9); // Derefter liste lastPartition = subSets.get (2); Liste forventetLastPartition = Lister. newArrayList (7, 8, 9); assertThat (lastPartition, equalTo (forventetLastPartition)); }

4. Brug Apache Commons-samlinger til at opdele listen

De seneste udgivelser af Apache Commons Collections har for nylig tilføjet understøttelse til partitionering af en liste:

@Test offentligt ugyldigt givenList_whenParitioningIntoNSublists_thenCorrect () {List intList = Lists.newArrayList (1, 2, 3, 4, 5, 6, 7, 8); Liste subSets = ListUtils.partition (intList, 3); Liste lastPartition = subSets.get (2); Liste forventetLastPartition = Lister. newArrayList (7, 8); assertThat (subSets.size (), equalTo (3)); assertThat (lastPartition, equalTo (forventetLastPartition)); }

Der er ingen tilsvarende mulighed for at opdele en rå samling - svarende til Guava Iterables.partition i Commons Collections.

Endelig gælder den samme advarsel også her - den resulterende partition er visninger af den oprindelige liste.

5. Brug Java8 til at opdele listen

Lad os nu se, hvordan du bruger Java8 til at opdele vores liste.

5.1. Samlere partitionering af

Vi kan bruge Collectors.partitioningBy () at opdele listen i 2 underlister - som følger:

@Test offentligt ugyldigt givetList_whenParitioningIntoSublistsUsingPartitionBy_thenCorrect () {List intList = Lists.newArrayList (1, 2, 3, 4, 5, 6, 7, 8); Kort grupper = intList.stream (). indsamle (Collectors.partitioningBy (s -> s> 6)); Liste subSets = ny ArrayList(group.values ​​()); Liste lastPartition = subSets.get (1); Liste forventetLastPartition = Lister. newArrayList (7, 8); assertThat (subSets.size (), equalTo (2)); assertThat (lastPartition, equalTo (forventetLastPartition)); }

Bemærk: De resulterende partitioner er ikke en visning af hovedlisten, så ændringer, der sker på hovedlisten, påvirker ikke partitionerne.

5.2. Samlere grupperingBy

Vi kan også bruge Collectors.groupingBy () for at opdele vores liste til flere partitioner:

@Test offentlig endelig ugyldighed givenList_whenParitioningIntoNSublistsUsingGroupingBy_thenCorrect () {List intList = Lists.newArrayList (1, 2, 3, 4, 5, 6, 7, 8); Kort grupper = intList.stream (). indsamle (Collectors.groupingBy (s -> (s - 1) / 3)); Liste subSets = ny ArrayList(group.values ​​()); Liste lastPartition = subSets.get (2); Liste forventetLastPartition = Lister. newArrayList (7, 8); assertThat (subSets.size (), equalTo (3)); assertThat (lastPartition, equalTo (forventetLastPartition)); }

Bemærk: Ligesom Collectors.partitioningBy () - de resulterende partitioner påvirkes ikke af ændringer i hovedlisten.

5.3. Opdel listen efter separator

Vi kan også bruge Java8 til at opdele vores liste efter separator:

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

Bemærk: Vi brugte "0" som separator - vi opnåede først indekserne for alle "0" -elementer i listen, så delte vi Liste på disse indekser.

6. Konklusion

Løsningerne, der præsenteres her, bruger yderligere biblioteker - Guava eller Apache Commons Collections-biblioteket. Begge disse er meget lette og generelt nyttige, så det giver god mening at have en af ​​dem på klassestien; Men hvis det ikke er en mulighed - vises en eneste Java-løsning her.

Implementeringen af ​​alle disse eksempler og kodestykker kan findes på GitHub- dette er et Maven-baseret projekt, så det skal være let at importere og køre som det er.