当サイトは、アフィリエイト広告を利用しています
従来は for 文の二重ループなどを使って突合せをしていたがjava8の
streamのflatMap等を使用して行うことができた。
2個のListを突き合わせて
を行う方法をそれぞれまとめる。
2個の配列やListを突き合わせて指定した条件に一致しているもののみのListを新しく作る。
flatMap内でfilterを使って実現する。
サンプルオブジェクトクラス。
ここより下記のソースではすべてこのクラスのインスタンスを使用する。
//サンプルオブジェクトクラスclass Person{// 名前String name;String firstName;// セッターvoid setName(String name){this.name = name;}// ゲッターString getName(){return this.name;}void setFirstName(String firstName){this.firstName = firstName;}// ゲッターString getFirstName(){return this.firstName;}@Overridepublic String toString(){return "{" + "name : "+ this.name + ", " + "firstName : " + this.firstName + "}";}}
オブジェクトの中身出力については下記の記事で紹介しています。
二つの配列を突合せするパターン。
strermAPIのflatMapとfilterを使って実現する
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {// Your code here!List<String>strList1 = Arrays.asList("1","2","3","4","5","6");List<String>strList2 = Arrays.asList("2","5","6");// 突合せ処理List<String>muchList = strList1.stream().flatMap(str1val -> strList2.stream().filter(str2val -> str1val.equals(str2val))).collect(Collectors.toList());System.out.println(muchList);}}// 結果// 二つのlistの一致してる値だけのlistができる// muchList :2,5,6
streamのflatMapとfilterメソッドを使って下記の2個のList
を突き合わせて、指定した条件に一致したオブジェクトのみのListを作る。
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {// 突き合わせるListList<Person>mstList = new ArrayList<>();List<Person>trnList = new ArrayList<>();// マスタListに値を詰めるfor(int i=0;i<5;i++){Person personObj1 = null;personObj1 = new Person();personObj1.setName(String.valueOf(i) + "takashi");mstList.add(personObj1);}// マスタList確認System.out.println("【マスタList】");mstList.stream().forEach(ob1 ->{System.out.println(ob1);});System.out.println("");// トランザクションListに値を詰めるfor(int i=2;i<10;i++){Person personObj2 = null;personObj2 = new Person();personObj2.setName(String.valueOf(i) + "takashi");personObj2.setFirstName(String.valueOf(i) + "tanaka");trnList.add(personObj2);}// トランザクションList確認System.out.println("【トランザクションList】");trnList.stream().forEach(ob2 ->{System.out.println(ob2);});System.out.println("");// 突合せ処理List<Person>resultList = mstList.stream().flatMap(mstObj -> trnList.stream().filter(trnObj -> mstObj.getName().equals(trnObj.getName()))).collect(Collectors.toList());// 突合せ結果System.out.println("【nameが一致したオブジェクトList】");resultList.stream().forEach(muchObj ->System.out.println(muchObj));}}
実行結果を確認する
【マスタList】{name : 0takashi, firstName : null}{name : 1takashi, firstName : null}{name : 2takashi, firstName : null}{name : 3takashi, firstName : null}{name : 4takashi, firstName : null}【トランザクションList】{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}{name : 5takashi, firstName : 5tanaka}{name : 6takashi, firstName : 6tanaka}{name : 7takashi, firstName : 7tanaka}{name : 8takashi, firstName : 8tanaka}{name : 9takashi, firstName : 9tanaka}【nameが一致したオブジェクトList】{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}
【nameが一致したオブジェクトList】が取得できている。
一致した場合にresultListに格納されるのはfilterでループしてる方のオブジェクトになる。
※この例だとトランザクションList(trnList)のオブジェクト。
動作確認したオンラインソースを下記に載せます。
上記はstream内を省略したので省略なしで書いてみる
import java.util.*;import java.util.stream.Collectors;import java.util.stream.Stream;public class Main {public static void main(String[] args) throws Exception {// 突き合わせるListList<Person>mstList = new ArrayList<>();List<Person>trnList = new ArrayList<>();// マスタListに値を詰めるfor(int i=0;i<5;i++){Person personObj1 = null;personObj1 = new Person();personObj1.setName(String.valueOf(i) + "takashi");mstList.add(personObj1);}// マスタList確認System.out.println("【マスタList】");mstList.stream().forEach(ob1 ->{System.out.println(ob1);});System.out.println("");// トランザクションListに値を詰めるfor(int i=2;i<10;i++){Person personObj2 = null;personObj2 = new Person();personObj2.setName(String.valueOf(i) + "takashi");personObj2.setFirstName(String.valueOf(i) + "tanaka");trnList.add(personObj2);}// トランザクションList確認System.out.println("【トランザクションList】");trnList.stream().forEach(ob2 ->{System.out.println(ob2);});System.out.println("");//突合せ処理(省略なし)List<Person>resultList = mstList.stream().flatMap(mstObj -> {Stream<Person>streamList = trnList.stream().filter(trnObj -> mstObj.getName().equals(trnObj.getName()));return streamList;}).collect(Collectors.toList());// 突合せ結果System.out.println("【一致したオブジェクトのList】");resultList.stream().forEach(muchObj ->System.out.println(muchObj));}}
実行結果を確認する
【マスタList】{name : 0takashi, firstName : null}{name : 1takashi, firstName : null}{name : 2takashi, firstName : null}{name : 3takashi, firstName : null}{name : 4takashi, firstName : null}【トランザクションList】{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}{name : 5takashi, firstName : 5tanaka}{name : 6takashi, firstName : 6tanaka}{name : 7takashi, firstName : 7tanaka}{name : 8takashi, firstName : 8tanaka}{name : 9takashi, firstName : 9tanaka}【一致したオブジェクトのList】{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}
flatMapが何をしているのかを少し調べて見る
試しにflatMapではなくmapを使ってみる
mapを使ってmap内のfilterの戻り値に何が帰ってきているかを調べる。
import java.util.*;import java.util.stream.Collectors;import java.util.stream.Stream;public class Main {public static void main(String[] args) throws Exception {// 突き合わせるListList<Person>mstList = new ArrayList<>();List<Person>trnList = new ArrayList<>();// マスタListに値を詰めるfor(int i=0;i<5;i++){Person personObj1 = null;personObj1 = new Person();personObj1.setName(String.valueOf(i) + "takashi");mstList.add(personObj1);}// マスタList確認System.out.println("【マスタList】");mstList.stream().forEach(ob1 ->{System.out.println(ob1);});System.out.println("");// トランザクションListに値を詰めるfor(int i=2;i<10;i++){Person personObj2 = null;personObj2 = new Person();personObj2.setName(String.valueOf(i) + "takashi");personObj2.setFirstName(String.valueOf(i) + "tanaka");trnList.add(personObj2);}// トランザクションList確認System.out.println("【トランザクションList】");trnList.stream().forEach(ob2 ->{System.out.println(ob2);});System.out.println("");// 突合せ処理(mapで確認してみる)//mapの結果はlistlistで帰ってきているため、flatMapで次元をあげてやる必要がある//coListはListListには変換できないList<Object> resultList = mstList.stream().map(mstObj -> {Stream<Person>streamList = trnList.stream().filter(trnObj -> mstObj.getName().equals(trnObj.getName()));System.out.println("【stream内のfilterの結果】: " + streamList.collect(Collectors.toList()));return streamList;}).collect(Collectors.toList());}}
実行結果を確認する
【マスタList】{name : 0takashi, firstName : null}{name : 1takashi, firstName : null}{name : 2takashi, firstName : null}{name : 3takashi, firstName : null}{name : 4takashi, firstName : null}【トランザクションList】{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}{name : 5takashi, firstName : 5tanaka}{name : 6takashi, firstName : 6tanaka}{name : 7takashi, firstName : 7tanaka}{name : 8takashi, firstName : 8tanaka}{name : 9takashi, firstName : 9tanaka}【stream内のfilterの結果】: []【stream内のfilterの結果】: []【stream内のfilterの結果】: [{name : 2takashi, firstName : 2tanaka}]【stream内のfilterの結果】: [{name : 3takashi, firstName : 3tanaka}]【stream内のfilterの結果】: [{name : 4takashi, firstName : 4tanaka}]
stream内で実行されているfilterの戻り値がListであることがわかる。
つまりmapの戻り値としては下記のようにList< List < Person >>の形になっている。
[[],[],[],[{name : 2takashi, firstName : 2tanaka}],[{name : 3takashi, firstName : 3tanaka}],[{name : 4takashi, firstName : 4tanaka}],]
このままではList< Person >型では受け取れないので
flatMapで平坦にして受け取っている。
イメージとしては下記のような感じになる。
[{name : 2takashi, firstName : 2tanaka},{name : 3takashi, firstName : 3tanaka},{name : 4takashi, firstName : 4tanaka},]
flatMapで中のList< List < Person >>を一次元あげて、
List < Person >で受け取れるようにしている
mapで動作確認したオンラインソースを載せときます。
streamのmapとanyMatchメソッドを使って下記の2個のList
を突き合わせて、指定した条件に一致した場合に
固定値でマスタListのオブジェクトを更新する
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {// 突き合わせるListList<Person>mstList = new ArrayList<>();List<Person>trnList = new ArrayList<>();// マスタListに値を詰めるfor(int i=0;i<5;i++){Person personObj1 = null;personObj1 = new Person();personObj1.setName(String.valueOf(i) + "takashi");mstList.add(personObj1);}// マスタList確認System.out.println("【マスタList】");mstList.stream().forEach(ob1 ->{System.out.println(ob1);});System.out.println("");// トランザクションListに値を詰めるfor(int i=2;i<10;i++){Person personObj2 = null;personObj2 = new Person();personObj2.setName(String.valueOf(i) + "takashi");personObj2.setFirstName(String.valueOf(i) + "tanaka");trnList.add(personObj2);}// トランザクションList確認System.out.println("【トランザクションList】");trnList.stream().forEach(ob2 ->{System.out.println(ob2);});System.out.println("");// 突合せ更新処理(固定値)List<Person>resultList = mstList.stream().map(mstObj -> {//トランザクションListを検索するboolean result = trnList.stream().anyMatch(trnObj -> mstObj.getName().equals(trnObj.getName()));if(result){mstObj.setName("一致");}return mstObj;}).collect(Collectors.toList());// 突合せ固定値更新結果System.out.println("【更新後マスタList】");resultList.stream().forEach(muchObj ->System.out.println(muchObj));}}
実行結果を確認する
【マスタList】{name : 0takashi, firstName : null}{name : 1takashi, firstName : null}{name : 2takashi, firstName : null}{name : 3takashi, firstName : null}{name : 4takashi, firstName : null}【トランザクションList】{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}{name : 5takashi, firstName : 5tanaka}{name : 6takashi, firstName : 6tanaka}{name : 7takashi, firstName : 7tanaka}{name : 8takashi, firstName : 8tanaka}{name : 9takashi, firstName : 9tanaka}【更新後マスタList】{name : 0takashi, firstName : null}{name : 1takashi, firstName : null}{name : 一致, firstName : null}{name : 一致, firstName : null}{name : 一致, firstName : null}
一致しているnameが更新されたオブジェクトのListが取得できる。
streamのanyMatchの使い方については下記記事で紹介しています!
実際に動かしてみたオンラインソースを下記に載せます。
streamのmap,filter,findfirstメソッドを使って2個のList
を突き合わせて、指定した条件に一致した場合に一致したトランザクションListのオブジェクトの値で
マスタListのオブジェクトの値を更新する。
anyMatchでは結果はboolean型で返却されるため、
一致したオブジェクトまではわからなかったが
filterとfindfirstを使うことで一致したオブジェクトを特定することができる。
突き合わせを実行するクラス
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {// 突き合わせるListList<Person>mstList = new ArrayList<>();List<Person>trnList = new ArrayList<>();// マスタListに値を詰めるfor(int i=0;i<5;i++){Person personObj1 = null;personObj1 = new Person();personObj1.setName(String.valueOf(i) + "takashi");mstList.add(personObj1);}// マスタList確認System.out.println("【マスタList】");mstList.stream().forEach(ob1 ->{System.out.println(ob1);});System.out.println("");// トランザクションListに値を詰めるfor(int i=2;i<10;i++){Person personObj2 = null;personObj2 = new Person();personObj2.setName(String.valueOf(i) + "takashi");personObj2.setFirstName(String.valueOf(i) + "tanaka");trnList.add(personObj2);}// トランザクションList確認System.out.println("【トランザクションList】");trnList.stream().forEach(ob2 ->{System.out.println(ob2);});System.out.println("");// 突合せ更新処理(オブジェクトの値)List<Person>resultList = mstList.stream().map(mstObj -> {//トランザクションListを検索するPerson result = trnList.stream().filter(trnObj -> mstObj.getName().equals(trnObj.getName())).findFirst().orElse(null);if(Objects.nonNull(result)){//一致してる場合更新mstObj.setFirstName(result.getFirstName());}return mstObj;}).collect(Collectors.toList());// 突合せ更新結果System.out.println("【更新後マスタList】");resultList.stream().forEach(muchObj ->System.out.println(muchObj));}}
実行結果を確認する
【マスタList】{name : 0takashi, firstName : null}{name : 1takashi, firstName : null}{name : 2takashi, firstName : null}{name : 3takashi, firstName : null}{name : 4takashi, firstName : null}【トランザクションList】{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}{name : 5takashi, firstName : 5tanaka}{name : 6takashi, firstName : 6tanaka}{name : 7takashi, firstName : 7tanaka}{name : 8takashi, firstName : 8tanaka}{name : 9takashi, firstName : 9tanaka}【更新後マスタList】{name : 0takashi, firstName : null}{name : 1takashi, firstName : null}{name : 2takashi, firstName : 2tanaka}{name : 3takashi, firstName : 3tanaka}{name : 4takashi, firstName : 4tanaka}
マスタListの中でトランザクションListのオブジェクトのnameと
一致しているオブジェクトのfirstNameが一致しているトランザクションListの
オブジェクトのfirstNameで更新されている。
動作確認したオンラインソースを下記の載せます。
トランザクションListから指定した条件に一致しているオブジェクトを探す際
findfirstを使用しているため、トランザクションListに指定した条件に当てはまる
オブジェクトが複数存在する場合は、最初に見つかった方しか取得できない。
そのため指定する条件はユニークにする必要がある。
findFirstの使い方については下記記事で紹介しています!
下記の本ではjava8のstreamについて詳しく記載があるのでおすすめです。