☕️

StreamAPIでリストを分割する

2024/09/12に公開

やりたかったこと

  • StreamAPIで、1つのリストを、条件次第で別々のリストに分けたい
    • 命令的に書くなら、先に作ったArrayの中に.add()で詰め込んでいくだけなので簡単
    • だが、Java8以降なのでStreamを使いたい
  • 条件による分類は1回で済ませたい
    • 実際に使うときは複雑な条件を適用させる想定
    • なので、同じリストに異なる条件を複数回適用してリスト生成、みたいなことはしたくなかった

実装

2種類に分割

Collectors.partitioningBy()を使用する

2種類に分類
// 分類対象のIntegerリストを生成
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

// partitioningByを使って偶数奇数に分類したmapを生成する
Map<Boolean, List<Integer>> map = list.stream()
    .collect(Collectors.partitioningBy(i -> i % 2 == 0));

// 偶数だけ取得
List<Integer> even = map.get(true);
System.out.println("even: " + even);

// 奇数だけ取得
List<Integer> odd = map.get(false);
System.out.println("odd: " + odd);
結果
even: [2, 4]
odd: [1, 3, 5]
  • Collectors.partitioningBy()の条件次第で、trueのリストかfalseのリストのどちらかに入れるようにする
  • それを.get(bool)で取り出す

3種類以上に分割

Collectors.groupingBy()とenumを使う

3種類に分類
public class Main {
    enum StartCategory {
        STARTS_WITH_A, STARTS_WITH_B, OTHERS
    }

    public static void main(String[] args) {
        List<String> words = Arrays.asList("Apple", "Banana", "Apricot", "Blueberry", "Cherry");

        Map<StartCategory, List<String>> groupedByStart = words.stream()
                .collect(Collectors.groupingBy(Main::getStartCategory));

        List<String> startWithA = groupedByStart.get(StartCategory.STARTS_WITH_A);
        System.out.println("Aで始まる: " + startWithA);
        
        List<String> startWithB = groupedByStart.get(StartCategory.STARTS_WITH_B);
        System.out.println("Bで始まる: " + startWithB);
        
        List<String> others = groupedByStart.get(StartCategory.OTHERS);
        System.out.println("その他: " + others);
    }

    private static StartCategory getStartCategory(String word) {
        if (word.startsWith("A")) {
            return StartCategory.STARTS_WITH_A;
        } else if (word.startsWith("B")) {
            return StartCategory.STARTS_WITH_B;
        } else {
            return StartCategory.OTHERS;
        }
    }
結果
Aで始まる: [Apple, Apricot]
Bで始まる: [Banana, Blueberry]
その他: [Cherry]
  • enumを作って分類する
  • それを.get(enum)で取り出す

Discussion