はじめに
RDB(リレーショナルデータベース) において SQL で AND条件で検索するような感じで、
Map<項目名,値> に設定した条件で、List< Map<項目名,値>> の内容をフィルタリングする例です。
フィルタリング方法
抽出対象のレコードを stream の filter で 絞り込み、Collectors.toList で新たなリストに集約します。
filter内では、Mapエントリを stream の allMatch (=AND条件なので) で 条件の値比較をします。
List< Map<String, Object> > result = 《抽出対象のレコード》.stream().filter(
row -> 《抽出条件のマップ》.entrySet().stream().allMatch( map -> 《row.get( map.getKey() ) と map.getValue() を比較しOK なら true を返却する式》 ) ).collect( Collectors.toList() );
以下のような場合に使えるかもしれません。
- フィルタリング対象のレコードが数万件にならないデータを RDB を介したくない場合
- 条件のみ入れ替えて都度データ抽出が必要な場合
テストデータ・テスト結果もこみ込みで、ソースコードを書いています。参考にしてください。
import java.util.List;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Map;
import java.util.Random;
import java.util.HashMap;
import java.util.stream.Collectors;
class filterTest {
public static void main(String args[]) {
//フィルタリング対象のデータをセット
List< Map<String, Object> > rows = setTestData();
//フィルタリングする値
Map< String, Object > filterMap = new HashMap<>();
filterMap.put( "value1", "A" );
filterMap.put( "value2", Integer.valueOf( 1 ) );
System.out.println("フィルタリング前の出力 -----");
//フィルタリング前の出力
rows.stream().forEach(row -> System.out.println( MessageFormat.format( "key= {0} (value1= {1}, value2= {2})", row.get("key"), row.get("value1"), row.get("value2"))));
System.out.println("フィルタリング後の出力 -----");
//フィルタリング処理
List< Map<String, Object> > result = rows.stream().filter(
row -> filterMap.entrySet().stream().allMatch( map -> equals( row.get( map.getKey() ), map.getValue() ) )
).collect( Collectors.toList() );
//フィルタリング結果の出力
result.stream().forEach(row -> System.out.println( MessageFormat.format( "key= {0} (value1= {1}, value2= {2})", row.get("key"), row.get("value1"), row.get("value2"))));
}
/**
* テストデータの設定( key,val1,val2 カラムで構成されるRDBテーブルレコードを想定)
* key : String, value1 : String, value2 : Integer
* @return テストデータリスト
*/
public static List<Map<String, Object>> setTestData() {
//オブジェクトの初期化
List< Map<String, Object> > rows = new ArrayList< Map<String, Object> >();
Random random = new Random();
//1000件分のテストデータを作成する
for(int i = 0; i < 1000; i++) {
Map<String, Object> row = new HashMap<String, Object>();
row.put("key", String.valueOf(i + 1));
row.put("value1", new String(Character.toChars(random.nextInt( 26 ) + 65)) );
row.put("value2", random.nextInt( 10 ) );
rows.add(row);
}
return rows;
}
private static boolean equals( final Object obj1, final Object obj2 ) {
if ( obj1 != null ) return obj1.equals( obj2 );
if ( obj2 != null ) return obj2.equals( obj1 );
return true;
}
}

