Rozdeľte zoznam na Java

1. Prehľad

V tomto návode to ilustrujem ako rozdeliť Zoznam na niekoľko podzoznamov danej veľkosti.

Pre pomerne jednoduchú operáciu prekvapivo neexistuje podpora v štandardných rozhraniach API na zhromažďovanie Java. Našťastie Guava aj Apache Commons Collections implementovali operáciu podobným spôsobom.

Tento článok je súčasťou „Java - späť na základné”Séria tu na Baeldungu.

2. Na rozdelenie zoznamu použite program Guava

Guava uľahčuje rozdelenie Zoznamu na podlisty určenej veľkosti - cez the Zoznamy. Oddiel prevádzka:

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

3. Na rozdelenie zbierky použite Guava

Rozdelenie zbierky je možné aj s Guavou:

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

Majte na pamäti, že priečky sú podzoznamové pohľady na pôvodnú zbierku - čo znamená, že zmeny v pôvodnej kolekcii sa prejavia v oddieloch:

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

4. Na rozdelenie zoznamu použite zbierky Apache Commons

Najnovšie vydania zbierok Apache Commons nedávno pridali podporu aj pre rozdelenie zoznamu:

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

Existuje žiadna zodpovedajúca možnosť rozdeliť nespracovanú kolekciu - podobný oddielu Guava Iterables.part v zbierkach Commons.

Nakoniec platí rovnaká výhrada aj tu - výsledný oddiel sú pohľadmi na pôvodný Zoznam.

5. Na rozdelenie zoznamu použite program Java8

Teraz sa pozrime, ako používať Java8 na rozdelenie nášho Zoznamu.

5.1. Zberatelia rozdelenieBy

Môžeme použiť Collectors.partitioningBy () rozdeliť zoznam na 2 podskupiny - nasledovne:

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

Poznámka: Výsledné oddiely nie sú zobrazením hlavného Zoznamu, takže akékoľvek zmeny, ktoré sa v hlavnom zozname vyskytnú, nebudú mať vplyv na oddiely.

5.2. Zberatelia zoskupenieBy

Môžeme tiež použiť Collectors.groupingBy () rozdeliť náš zoznam na viac oddielov:

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

Poznámka: Rovnako ako Collectors.partitioningBy () - výsledné oddiely nebudú ovplyvnené zmenami v hlavnom zozname.

5.3. Rozdeliť zoznam podľa oddeľovača

Môžeme tiež použiť Java8 na rozdelenie nášho Zoznamu podľa oddeľovača:

@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 (); Zoznam subSets = IntStream.range (0, indexes.length - 1) .mapToObj (i -> intList.subList (indexes [i] + 1, indexes [i + 1]))) .collect (Collectors.toList ()); Zoznam lastPartition = subSets.get (2); Zoznam expectLastPartition = Zoznamy. newArrayList (7, 8); assertThat (subSets.size (), equalTo (3)); assertThat (lastPartition, equalTo (expectLastPartition)); }

Poznámka: Ako oddeľovač sme použili „0“ - najskôr sme získali indexy všetkých „0“ prvkov v zozname, potom sme rozdelili Zoznam na týchto indexoch.

6. Záver

Tu uvedené riešenia využívajú ďalšie knižnice - Guava alebo knižnicu Apache Commons Collections. Oba sú veľmi ľahké a celkovo mimoriadne užitočné, takže má zmysel mať jedného z nich na triednej ceste; ak to však nie je možnosť - tu je zobrazené riešenie iba pre Javu.

Implementácia všetkých týchto príkladov a útržkov kódu nájdete na GitHub- toto je projekt založený na Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.


$config[zx-auto] not found$config[zx-overlay] not found