Partisi Daftar di Jawa

1. Ikhtisar

Dalam tutorial ini saya akan mengilustrasikan cara membagi List menjadi beberapa sublist dengan ukuran tertentu.

Untuk operasi yang relatif sederhana, yang mengejutkan tidak ada dukungan dalam API kumpulan Java standar. Untungnya, Guava dan Apache Commons Collections telah menerapkan operasi dengan cara yang sama.

Artikel ini adalah bagian dari seri “ Java - Kembali ke Dasar ” di Baeldung.

2. Gunakan Jambu Biji untuk Mempartisi Daftar

Guava memfasilitasi pembagian List ke dalam sublists dengan ukuran tertentu - melalui operasi 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. Gunakan Jambu Biji untuk Mempartisi Koleksi

Mempartisi Koleksi juga dapat dilakukan dengan Jambu Biji:

@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)); }
    

Perlu diingat bahwa partisi adalah tampilan sublist dari koleksi asli - yang berarti bahwa perubahan dalam koleksi asli akan tercermin di partisi:

@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. Gunakan Koleksi Apache Commons untuk Mempartisi Daftar

Rilis terbaru Koleksi Apache Commons baru-baru ini menambahkan dukungan untuk mempartisi Daftar juga:

@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)); }
    

Tidak ada opsi yang sesuai untuk mempartisi Koleksi mentah - mirip dengan Guava Iterables.partition di Commons Collections.

Terakhir, peringatan yang sama juga berlaku di sini - partisi yang dihasilkan adalah tampilan Daftar asli.

5. Gunakan Java8 untuk Mempartisi Daftar

Sekarang, mari kita lihat bagaimana menggunakan Java8 untuk mempartisi Daftar kita.

5.1. Partisi kolektor

Kita bisa menggunakan Collectors.partitioningBy () untuk membagi daftar menjadi 2 sublist - sebagai berikut:

@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)); }
      
     
    

Catatan: Partisi yang dihasilkan bukan tampilan Daftar utama, jadi perubahan apa pun yang terjadi pada Daftar utama tidak akan memengaruhi partisi.

5.2. Pengelompokan kolektor

Kita juga bisa menggunakan Collectors.groupingBy () untuk membagi daftar kita menjadi beberapa partisi:

@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)); }
      
     
    

Catatan: Sama seperti Collectors.partitioningBy () - partisi yang dihasilkan tidak akan terpengaruh oleh perubahan dalam Daftar utama.

5.3. Pisahkan Daftar dengan Pemisah

Kami juga dapat menggunakan Java8 untuk membagi Daftar kami dengan pemisah:

@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)); }
    

Catatan: Kami menggunakan "0" sebagai pemisah - pertama-tama kami mendapatkan indeks dari semua elemen "0" dalam Daftar, lalu kami membagi Daftar pada indeks ini.

6. Kesimpulan

Solusi yang disajikan di sini menggunakan pustaka tambahan - Guava atau pustaka Koleksi Apache Commons. Keduanya sangat ringan dan sangat berguna secara keseluruhan, jadi masuk akal untuk memiliki salah satunya di classpath; namun, jika itu bukan pilihan - solusi khusus Java akan ditampilkan di sini.

Penerapan semua contoh dan cuplikan kode ini dapat ditemukan di GitHub - ini adalah proyek berbasis Maven, jadi semestinya mudah untuk mengimpor dan menjalankannya apa adanya.