Javaにおけるリスト分割の実装手法

Javaにおいて、大規模なコレクションを処理する際、メモリ使用量の最適化や並列処理を可能にするため、リストを指定されたサイズのサブリストに分割する操作は一般的な要件です。この操作は、データのバッチ処理やページング、API呼び出しの制限対応など、様々な場面で活用されます。

Google Guavaライブラリを利用する方法

GuavaはGoogleが提供するユーティリティライブラリで、Lists.partition()メソッドを使用して簡潔にリストを分割できます。

import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.List;

public class ListPartitioningExample {
    public static void main(String[] args) {
        List<String> celestialBodies = Arrays.asList(
            "Mercury", "Venus", "Earth", "Mars", 
            "Jupiter", "Saturn", "Uranus", "Neptune"
        );
        List<List<String>> partitioned = Lists.partition(celestialBodies, 3);
        System.out.println(partitioned);
    }
}

上記コードの実行結果は以下の通りです:

[[Mercury, Venus, Earth], [Mars, Jupiter, Saturn], [Uranus, Neptune]]

依存関係の追加(Mavenプロジェクトの場合):

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.2-jre</version>
</dependency>

Apache Commons Collectionsを利用する方法

Apache Commons CollectionsのListUtils.partition()メソッドも同様の機能を提供します。

import org.apache.commons.collections4.ListUtils;
import java.util.Arrays;
import java.util.List;

public class CommonsPartitionExample {
    public static void main(String[] args) {
        List<String> elements = Arrays.asList(
            "Alpha", "Beta", "Gamma", "Delta", 
            "Epsilon", "Zeta", "Eta", "Theta"
        );
        List<List<String>> segments = ListUtils.partition(elements, 4);
        System.out.println(segments);
    }
}

実行結果:

[[Alpha, Beta, Gamma, Delta], [Epsilon, Zeta, Eta, Theta]]

Maven依存関係:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version>
</dependency>

Hutoolライブラリを利用する方法

Hutoolは中国発の多機能ユーティリティライブラリで、ListUtil.partition()メソッドを使用できます。

import cn.hutool.core.collection.ListUtil;
import java.util.Arrays;
import java.util.List;

public class HutoolPartitionDemo {
    public static void main(String[] args) {
        List<String> items = Arrays.asList(
            "Apple", "Banana", "Cherry", "Date", 
            "Elderberry", "Fig", "Grape", "Honeydew"
        );
        List<List<String>> chunks = ListUtil.partition(items, 5);
        System.out.println(chunks);
    }
}

実行結果:

[[Apple, Banana, Cherry, Date, Elderberry], [Fig, Grape, Honeydew]]

Maven依存関係:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.22</version>
</dependency>

手動実装によるカスタム分割

外部ライブラリに依存せず、標準APIのみで実装する方法です。この実装はサブリストのビューを返し、元のリストへの変更がサブリストに反映される点に注意が必要です。

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CustomListPartitioner {
    public static <T> List<List<T>> split(List<T> source, int chunkSize) {
        if (chunkSize <= 0) {
            throw new IllegalArgumentException("Chunk size must be positive");
        }
        
        return new AbstractList<List<T>>() {
            @Override
            public List<T> get(int index) {
                int start = index * chunkSize;
                int end = Math.min(start + chunkSize, source.size());
                if (start >= end) {
                    throw new IndexOutOfBoundsException();
                }
                return source.subList(start, end);
            }
            
            @Override
            public int size() {
                return (int) Math.ceil((double) source.size() / chunkSize);
            }
        };
    }
    
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80, 90);
        List<List<Integer>> groups = split(numbers, 4);
        System.out.println(groups);
    }
}

実行結果:

[[10, 20, 30, 40], [50, 60, 70, 80], [90]]

タグ: Java Guava Apache Commons Hutool リスト分割

7月25日 00:42 投稿