当サイトは、アフィリエイト広告を利用しています

【java8】streamAPIのmapメソッドの使いどころ

作成日:2023月02月12日
更新日:2023年12月14日

java8のStreamAPIのmapメソッドの使いどころを
まとめていく。
javaで実装していてstreamを使う中ではfilterと並んで
よく使う。
また他のstreamAPIのメソッド(filterなど)と
組み合わせで使うことも多い

下記の本では streamAPI についても詳しく書いてありおススメです!

また当ブログで紹介しているjava8のstreamAPIを使った
コレクションや配列の操作方法を
下記記事でメソッド別にまとめています!

mapメソッドとは?

mapメソッドは配列またはlistの各要素に対して
指定した処理を実行できる中間操作メソッド
※中間操作であるため取り出すには終端操作をする必要がある。

mapメソッドのサンプル

簡単なサンプルを書いてみる

mapのサンプル
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class Main {
public static void main(String[] args) throws Exception {
//数値のリストを作成
List<Integer>sampleList = new ArrayList<>(Arrays.asList(1,2,3,4,5));
sampleList.stream().forEach(val->System.out.print(val));
//mapで加工処理をする
sampleList = sampleList.stream().map(val->val+1).collect(Collectors.toList());
System.out.println("");
sampleList.stream().forEach(val->System.out.print(val));
}
}
// 実行結果
// 12345
// 23456

mapメソッドを使ってリストの要素の数値にそれぞれ1を加算している。

mapメソッドのつかいどころ

とまぁ、上記サンプルを書いてみたが実際、プログラムを書くときに
あまり上記をようなパターン使うことはないので、自分がよく使うパターン
をまとめていく。

よく使うのか下記の3パターンが多い。

  • 既存のlistから新しいlistを作る
  • list内のオブジェクトの型を変換する
  • 二つのlistのマッチング処理

サンプルでは下記のオブジェクトクラスを使用する

Person.java
public class Person {
private final int id;
private final String name;
private final String address;
private final int age;
Person(int id,String name, String address,int age) {
this.id = id;
this.name = name;
this.address = address;
this.age = age;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getAddress() {
return this.address;
}
public int getAge() {
return this.age;
}
@Override
public String toString()
{
return "{" + this.id + " " + this.name + " " + this.address + " " + this.age +"}";
}
}

既存のlistから新しいlistを作る

既存のlistでは後続の処理で、使いづらい時などは
先にmapメソッドを使って使い安いように加工した新しいlistを作る
ことはよくある。

オブジェクトのlistから特定の属性のみのlistを作る①

単純に一つの属性のみを取り出してlistを作る

Main.java
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class Main {
public static void main(String[] args) throws Exception {
// オブジェクトのListを生成
List<Person>listBase = new ArrayList<>();
for(int i=0;i<5;i++){
Person pobj = new Person(i,"takashi"+i,"東京"+ i + "番地",i + 10);
listBase.add(pobj);
}
System.out.println("加工前");
System.out.println(listBase);
//mapで加工処理をする
List<String>listEdit = listBase.stream().map(p->p.getName()).collect(Collectors.toList());
System.out.println("加工後");
System.out.println(listEdit);
}
}
// 実行結果
// 加工前
// [{0 takashi0 東京0番地 10}, {1 takashi1 東京1番地 11}, {2 takashi2 東京2番地 12}, {3 takashi3 東京3番地 13}, {4 takashi4 東京4番地 14}]
// 加工後
// [takashi0, takashi1, takashi2, takashi3, takashi4]

nameだけのlistを作る。

実行サンプルを載せときます。

オブジェクトのlistから特定の属性のみのlistを作る①

オブジェクトのlistから特定の属性のみのlistを作る②

属性を取り出して加工することもできる。

Main.java
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class Main {
public static void main(String[] args) throws Exception {
// オブジェクトのListを生成
List<Person>listBase = new ArrayList<>();
for(int i=0;i<5;i++){
Person pobj = new Person(i,"takashi"+i,"東京"+ i + "番地",i + 10);
listBase.add(pobj);
}
System.out.println("加工前");
System.out.println(listBase);
//mapで加工処理をする
List<String>listEdit = listBase.stream().map(p->p.getName() + p.getAddress()).collect(Collectors.toList());
System.out.println("加工後");
System.out.println(listEdit);
}
}
// 実行結果
// 加工前
// [{0 takashi0 東京0番地 10}, {1 takashi1 東京1番地 11}, {2 takashi2 東京2番地 12}, {3 takashi3 東京3番地 13}, {4 takashi4 東京4番地 14}]
// 加工後
// [takashi0東京0番地, takashi1東京1番地, takashi2東京2番地, takashi3東京3番地, takashi4東京4番地]

nameとaddressを文字列結合した結果の要素を持つlistを作る
後述するマッチング処理とキーで突合せする前にに複合キーを作る時に
使ったりする

オブジェクトのlistから別オブジェクトのlistを作成する

mapメソッドを使って別のオブジェクトに変換する。
コンボボックス用のオブジェクトのlistを作る時など使うことがある。

サンプルではPersonオブジェクトのlistを下記のComboオブジェクトのlistに変換する

Combo.java
public class Combo {
private final String key;
private final String value;
Combo(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return this.key;
}
public String getValue() {
return this.value;
}
@Override
public String toString()
{
return "{" + this.key + " " + this.value +"}";
}
}

mapメソッドで新しいオブジェクトのlistを作成する

Main.java
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class Main {
public static void main(String[] args) throws Exception {
// オブジェクトのListを生成
List<Person>listBase = new ArrayList<>();
for(int i=0;i<5;i++){
Person pobj = new Person(i,"takashi"+i,"東京"+ i + "番地",i + 10);
listBase.add(pobj);
}
System.out.println("Personオブジェクトのlist");
System.out.println(listBase);
//mapで別のオブジェクトリストに変換する
List<Combo>listEdit = listBase.stream().map(p->{
Combo con = new Combo(String.valueOf(p.getId()),p.getName());
return con;
}).collect(Collectors.toList());
System.out.println("Comboオブジェクトのlist");
System.out.println(listEdit);
}
}
// 実行結果
// Personオブジェクトのlist
// [{0 takashi0 東京0番地 10}, {1 takashi1 東京1番地 11}, {2 takashi2 東京2番地 12}, {3 takashi3 東京3番地 13}, {4 takashi4 東京4番地 14}]
// Comboオブジェクトのlist
// [{0 takashi0}, {1 takashi1}, {2 takashi2}, {3 takashi3}, {4 takashi4}]

Personオブジェクトのlistからomboオブジェクトのlistを作成できている

サンプル実装をのせときます

オブジェクトのlistから別オブジェクトのlistを作成する

list内のオブジェクトの型を変換する

用途としてはmapメソッドを使って、チェインする streamAPIの

  • reduce
  • sorted
  • filter

などの処理を行えるようにする

reduceとの組み合わせ

reduceと組わせてみる

Main.java
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class Main {
public static void main(String[] args) throws Exception {
// オブジェクトのListを生成
List<Person>listBase = new ArrayList<>();
for(int i=0;i<5;i++){
Person pobj = new Person(i,"takashi"+i,"東京"+ i + "番地",i + 10);
listBase.add(pobj);
}
//mapメソッドでageのみのlistを作成
List<Integer>ageList = listBase.stream().map(p->p.getAge()).collect(Collectors.toList());
//reduceでageを合計する
int result = ageList.stream().reduce(0, (accum,value)->accum + value);
System.out.println(result);
//1文で書くver
int result2 = listBase.stream().map(p->p.getAge()).reduce(0, (accum,value)->accum + value);
System.out.println(result2);
}
}
// 実行結果
// 60
// 60

Personオブジェクトのままだとreduceが使えないので
reduceを使う前にmapメソッドで加工している。

サンプル実装をのせときます

【java8】map + recude

reduceメソッドについては下記記事でまとめています。

sortedとの組み合わせ

次はsortedとの組み合わせをしてみる。

Person.javaを少し変更する

java
public class Person {
private final String id;
private final String name;
private final String address;
private final int age;
Person(String id,String name, String address,int age) {
this.id = id;
this.name = name;
this.address = address;
this.age = age;
}
public String getId() {
return this.id;
}
public String setId() {
this.id = id;
}
public String getName() {
return this.name;
}
public String getAddress() {
return this.address;
}
public int getAge() {
return this.age;
}
@Override
public String toString()
{
return "{" + this.id + " " + this.name + " " + this.address + " " + this.age +"}";
}
}

idの型をStringにする これでmapなしでsortedメソッドを使ってみると...

java
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class Main {
public static void main(String[] args) throws Exception {
// オブジェクトのListを生成
List<Person>listBase = new ArrayList<>();
for(int i=0;i<12;i++){
Person pobj = new Person(String.valueOf(i),"takashi"+i,"東京"+ i + "番地",i + 10);
listBase.add(pobj);
}
//昇順でソート
listBase = listBase.stream().sorted(Comparator.comparing(Person::getId)).collect(Collectors.toList());
listBase.stream().forEach(v->System.out.println(v));
}
}
// 実行結果
// {0 takashi0 東京0番地 10}
// {1 takashi1 東京1番地 11}
// {10 takashi10 東京10番地 20}
// {11 takashi11 東京11番地 21}
// {2 takashi2 東京2番地 12}
// {3 takashi3 東京3番地 13}
// {4 takashi4 東京4番地 14}
// {5 takashi5 東京5番地 15}
// {6 takashi6 東京6番地 16}
// {7 takashi7 東京7番地 17}
// {8 takashi8 東京8番地 18}
// {9 takashi9 東京9番地 19}

idがStringであるためソートが狂ってしまう。

mapメソッドを使って

  • idをintに変換
  • idを前0埋めする

のどちらかをしてやることで正しくソートできる

Main.java
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class Main {
public static void main(String[] args) throws Exception {
// オブジェクトのListを生成
List<Person>listBase = new ArrayList<>();
for(int i=0;i<12;i++){
Person pobj = new Person(String.valueOf(i),"takashi"+i,"東京"+ i + "番地",i + 10);
listBase.add(pobj);
}
//mapメソッドでidをゼロ埋めしてからソートする
listBase = listBase.stream().map(p->{
String zeroPaddingVal = String.format("%02d",Integer.parseInt(p.getId()));
p.setId(zeroPaddingVal);
return p;
}).sorted(Comparator.comparing(Person::getId)).collect(Collectors.toList());
listBase.stream().forEach(v->System.out.println(v));
}
}
// 実行結果
// {00 takashi0 東京0番地 10}
// {01 takashi1 東京1番地 11}
// {02 takashi2 東京2番地 12}
// {03 takashi3 東京3番地 13}
// {04 takashi4 東京4番地 14}
// {05 takashi5 東京5番地 15}
// {06 takashi6 東京6番地 16}
// {07 takashi7 東京7番地 17}
// {08 takashi8 東京8番地 18}
// {09 takashi9 東京9番地 19}
// {10 takashi10 東京10番地 20}
// {11 takashi11 東京11番地 21}

サンプル実装をのせときます

【java8】map + sorted

sortedメソッドについては下記記事でまとめています。

二つのlistのマッチング処理

mapメソッドをfilterメソッドと組み合わせることで
二つのlistのマッチング処理を実行することができる
詳しくは下記記事でまとめています!

まとめ

java8のstreamAPIのmapメソッドの使いどころをサンプルを
使ってまとめてみた。
mapメソッドは単体で使うよりも他のstreamAIPのメソッドと組み合わせて
使うことでより便利になる。

新着記事

タグ別一覧
top