当サイトは、アフィリエイト広告を利用しています
java8のStreamAPIのtoMap(終端処理)を使って
Mapへの変換処理を行う方法をまとめる。
streamAPI については下記の本が詳しく書いてありおススメです!
また当ブログで紹介しているjava8のstreamAPIを使った
コレクションや配列の操作方法を
下記記事でメソッド別にまとめています!
forEachなどと同じStream内で加工された値を最終的に出力するcollectorの一つ。
toMapなのでMapオブジェクトの形に加工して出力する
引数の数で3パターンの使い方が可能。
引数はすべて関数型インターフェースで指定する。
引数には下記を指定する
両方とも一つの値を受け取って一つの値を返す関数型インターフェースのFunction型の
関数を指定する
// 構文.collect(Collectors.toMap(Function<T,R>,Function<T,R>))// 使用時のイメージ.collect(Collectors.toMap(e->e.getId(),e->getName()))// メソッド参照ver.collect(Collectors.toMap(Item::getId,Item::getName))
引数には下記を指定する
第一引数と第二引数は引数が二つの場合と同じ。
第三引数には二つの引数で一つの値を返す関数型インターフェースのBinaryOperator型の関数を指定する
// 構文.collect(Collectors.toMap(Function<T,R>,Function<T,R>,BinaryOperator<T>))// 使用時のイメージ.collect(Collectors.toMap(e->e.getId(),e->e.getName(),(oldVal,newVal) -> newVal))
引数には下記を指定する
第一引数~第三引数は引数は同じ。
第四引数には最終的に出力したいMapクラスを指定する。
// 構文.collect(Collectors.toMap(Function<T,R>,Function<T,R>,BinaryOperator<T>,Supplier<M> mapSupplier))// 使用時のイメージ.collect(Collectors.toMap(e->e.getId(),e->getName(),(oldVal,newVal) -> newVal,()->new LinkedHashMap<>()))// メソッド参照.collect(Collectors.toMap(Item::getId,Item::getName,(oldVal,newVal) -> newVal,LinkedHashMap::new))
実際にいくつかサンプルを実装してみる
PresonオブジェクトのListをnameをkeyにして
valueにPresonオブジェクト入れたLinkedHashMapを作成してみる
key重複の場合は後勝ちにする。
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {class Person {private final String name;private final int weight;Person(String name, int weight) {this.name = name;this.weight = weight;}public String getName() {return this.name;}public int getWeight() {return this.weight;}}List<Person> personList = Arrays.asList(new Person("太郎", 72),new Person("二郎", 79),new Person("二郎", 99));// オブジェクトリストをMapに変換するLinkedHashMap<String,Person>personMap =personList.stream().collect(Collectors.toMap(Person::getName, e -> e,(e1,e2)->e2,LinkedHashMap::new));// 変換したMapの中身をループで出力するpersonMap.entrySet().stream().forEach(map->{System.out.println(map.getKey()+"のインスタンス");System.out.println("Mapのkey : " + map.getKey());System.out.println("Mapのvalue(name) : " + map.getValue().getName());System.out.println("Mapのvalue(weight)" + map.getValue().getWeight());});}}// 実行結果// 太郎のインスタンス// Mapのkey : 太郎// Mapのvalue(name) : 太郎// Mapのvalue(weight)72// 二郎のインスタンス// Mapのkey : 二郎// Mapのvalue(name) : 二郎// Mapのvalue(weight)99
PresonオブジェクトのListをnameをkeyにして
valueにPresonオブジェクトのweight入れたLinkedHashMapを作成してみる
key重複の場合は先勝ちにする。
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {class Person {private final String name;private final int weight;Person(String name, int weight) {this.name = name;this.weight = weight;}public String getName() {return this.name;}public int getWeight() {return this.weight;}}List<Person> personList = Arrays.asList(new Person("太郎", 72),new Person("二郎", 79),new Person("二郎", 99));// オブジェクトリストをMapに変換するLinkedHashMap<String,Integer>personMap =personList.stream().collect(Collectors.toMap(Person::getName,Person::getWeight ,(e1,e2)->e1,LinkedHashMap::new));// 変換したMapの中身をループで出力するpersonMap.entrySet().stream().forEach(map->{System.out.println(map.getKey()+"のエントリー");System.out.println("Mapのkey : " + map.getKey());System.out.println("Mapのvalue : " + map.getValue());});}}// 太郎のエントリー// Mapのkey : 太郎// Mapのvalue : 72// 二郎のエントリー// Mapのkey : 二郎// Mapのvalue : 79
下記のようにtoMapを使う時にvalueの値がnullとなる場合はNullPointerExceptionが発生する。
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {class Person {private String name;private String weight;Person(String name, String weight) {this.name = name;this.weight = weight;}public String getName() {return this.name;}public String getWeight() {return this.weight;}public void setWeight(String weight) {this.weight = weight;}}List<Person> personList = Arrays.asList(// nullをセットnew Person("太郎", null),new Person("二郎", "79"),new Person("二郎", "99"));// オブジェクトリストをMapに変換するLinkedHashMap<String,String>personMap =personList.stream().collect(Collectors.toMap(Person::getName,Person::getWeight ,(e1,e2)->e1,LinkedHashMap::new));// 変換したMapの中身をループで出力するpersonMap.entrySet().stream().forEach(map->{System.out.println(map.getKey()+"のエントリー");System.out.println("Mapのkey : " + map.getKey());System.out.println("Mapのvalue : " + map.getValue());});}}
toMapメソッドは使えないのでcollectメソッドで直接作る。
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) throws Exception {class Person {private String name;private String weight;Person(String name, String weight) {this.name = name;this.weight = weight;}public String getName() {return this.name;}public String getWeight() {return this.weight;}public void setWeight(String weight) {this.weight = weight;}}List<Person> personList = Arrays.asList(new Person("太郎", null),new Person("二郎", "79"),new Person("二郎", "99"));// オブジェクトリストをMapに変換するMap<String,String>personMap =personList.stream().collect(// 中間コンテナを生成// 最初の1回だけ実行()->new HashMap<>(),// 中間コンテナに値をセットしていく// stermの要素の数だけ実行される(Map m,Person p)->m.put(p.getName(),p.getWeight()),// 中間コンテナからの結果をマージする// 順次ストリームの場合実行されない(m,m2)->m.putAll(m2));// 変換したMapの中身をループで出力するpersonMap.entrySet().stream().forEach(map->{System.out.println(map.getKey()+"のエントリー");System.out.println("Mapのkey : " + map.getKey());System.out.println("Mapのvalue : " + map.getValue());});}}// 二郎のエントリー// Mapのkey : 二郎// Mapのvalue : 99// 太郎のエントリー// Mapのkey : 太郎// Mapのvalue : null
メソッド参照で書くと下記のような感じになる。
// オブジェクトリストをMapに変換するMap<String,String>personMap =personList.stream().collect(// 中間コンテナを生成// 最初の1回だけ実行HashMap::new,// 中間コンテナに値をセットしていく// stermの要素の数だけ実行される(Map m,Person p)->m.put(p.getName(),p.getWeight()),// 中間コンテナからの結果をマージする// 順次ストリームの場合実行されないMap::putAll);
Java Stream でよく使う Map 変換
Java8のCollectors.toMap()の使い方
Streamのcollectメソッドを学ぶ