【Java】Listに格納したオブジェクトの値を条件に検索を行い、結果をListで取得

Listに格納したオブジェクトの値を条件に検索を行い、結果をListで取得

目的

やりたいことは、Listに格納したオブジェクトの値を条件にList内検索を行い、結果をListで取得します。

実現方法としては、java.util.Collection.streamとラムダ式を使います。

今回使用した環境

インターネット接続可能のオンラインの環境

64 ビット オペレーティング システム

Windows 10 22H2

Java 17

ソースコード

以下、文房具クラスです。コード、名前、価格のフィールドを持っています。今回はこの文房具クラスのオブジェクトをListに格納し、検索を行います。

public class Bunbougu {
    
    private String code; // コード 
    private String name; // 名前
    private int price;   // 価格
    
    @Override
    public String toString() {
        return code + "," + name + "," + String.valueOf(price);
    }
    
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
}

以下がList検索を行い、結果をリストで取得することを実現しているクラスです。複数条件指定にも対応しています。(と言っても、条件式をANDで指定しているだけですが…。)

import java.util.ArrayList;
import java.util.List;

public class FilterStart {

    public static void main(String[] args) {

        // 文房具のリストを作成
        List<Bunbougu> bunbouguList = new ArrayList<Bunbougu>();
        bunbouguList.add(new Bunbougu() {{
            setCode("0001");setName("色鉛筆");setPrice(300);
        }});
        bunbouguList.add(new Bunbougu() {{
            setCode("0002");setName("消しゴム");setPrice(150);
        }});
        bunbouguList.add(new Bunbougu() {{
            setCode("0003");setName("鉛筆");setPrice(50);
        }});
        bunbouguList.add(new Bunbougu() {{
            setCode("0004");setName("赤鉛筆");setPrice(100);
        }});
        
        // 価格が100以上、かつ名前に"鉛筆"を含む文房具を抽出
        List<Bunbougu> filterBunbouguList = bunbouguList.stream()
                    .filter(bunbougu -> bunbougu.getPrice() >= 100 && 
                                        bunbougu.getName().contains("鉛筆"))
                    .toList();
                    // .collect(Collectors.toList());
        
        // 上記でstream().toList()を使用した場合、
        // 抽出後のfilterBunbouguListにBunbouguインスタンスをaddしてしまうと
        // UnsupportedOperationExceptionが発生する
        // 対策としてはstream().toList()でなくstream().collect(Collectors.toList())
        // を使用することで例外発生を回避できる
        
        // stream().toList()を使用した場合、以下のコードは
        // UnsupportedOperationExceptionが発生するため、コメントアウト
        // filterBunbouguList.add(new Bunbougu() {{
        //     setCode("0005");setName("定規");setPrice(200);
        // }});
        
        // 抽出結果をコンソール出力
        for (Bunbougu bunbougu : filterBunbouguList) {
            System.out.println(bunbougu.toString());
        }
        
        // 行間を空ける
        System.out.println("");
        
        // またforEachを使ってこのように書くこともできる
        bunbouguList.stream()
                .filter(bunbougu -> bunbougu.getPrice() >= 100 && 
                                    bunbougu.getName().contains("鉛筆"))
                .forEach(bunbougu -> {
                    System.out.println(bunbougu.toString());
                });
    }
}

注意事項としては、ソース中にも書いてありますが、stream().toList()を使用して抽出したリストに対して項目の追加(add)を行ってしまうとUnsupportedOperationExceptionが発生します。

この例外を避けたい場合、stream().collect(Collectors.toList())を使いましょう。

動作確認

以下、実行結果です。

価格が100円以上で名前に「鉛筆」を含むリストを取得できました。


以上となります。

ここまでお読みいただきありがとうございました。

Java

Posted by だゆう