IntStreamインターフェースの集約操作
合計を求めるsum
IntStream
で要素の合計を求めるにはsum
を使います。
Java
System.out.println("sum関数:" + IntStream.of(1, 2, 3).sum());
実行結果
sum関数:6
最大値を求めるmax
IntStream
で要素の最大値を求めるにはmax
を使います。
max
はOptional型で返すので、int型で返したい場合はgetAsInt
を用います。
Java
System.out.println("max関数:" + IntStream.of(1, 2, 3).max().getAsInt());
実行結果
max関数:3
最小値を求めるmin
IntStream
で要素の最小値を求めるにはmin
を使います。
min
はOptional型で返すので、int型で返したい場合はgetAsInt
を用います。
Java
System.out.println("min関数:" + IntStream.of(1, 2, 3).min().getAsInt());
実行結果
min関数:1
個数を求めるcount
IntStream
で要素の個数を求めるにはcount
を使います。
Java
System.out.println("count関数:" + IntStream.of(1, 2, 3).count());
実行結果
count関数:3
平均を求めるaverage
IntStream
で要素の平均を求めるにはaverage
を使います。
average
はOptional型で返すので、Double型で返したい場合はgetAsDouble
を用います。
Java
System.out.println("average関数:" + IntStream.of(1, 2, 3).average().getAsDouble());
実行結果
average関数:2.0
任意のストリームで集約操作を行う
例えば以下のようなfood
クラスのデータを集約する場合を考えてみます。
Java
public class food {
String name; //名前
int price; //値段
String group;//カテゴリ
//コンストラクタ
public food(String name, int price, String group) {
super();
this.name = name;
this.price = price;
this.group = group;
}
//ゲッター・セッター
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;}
public String getgroup() {return group;}
public void setgroup(String group) {this.group = group;}
@Override
public String toString(){
return this.name + ":" + this.price + ":" + this.group;
}
}
投入するデータは次のとおりとします。
Java
//foodリストの生成
List<food> foodList = new ArrayList<>();
//foodリストにデータを詰める。
foodList.add(new food("キャベツ", 90, "野菜"));
foodList.add(new food("トマト", 130, "野菜"));
foodList.add(new food("ブロッコリー", 200, "野菜"));
foodList.add(new food("リンゴ", 100, "フルーツ"));
foodList.add(new food("オレンジ", 150, "フルーツ"));
foodList.add(new food("ぶどう", 200, "フルーツ"));
foodList.add(new food("イチゴ", 500, "フルーツ"));
foodList.add(new food("チョコレート", 80, "お菓子"));
foodList.add(new food("アメ", 50, "お菓子"));
foodList.add(new food("ケーキ", 1000, "お菓子"));
foodList.add(new food("ポテトチップス", 150, "お菓子"));
foodList.add(new food("クッキー", 120, "お菓子"));
ストリーム内の要素をすべて合計する
ストリーム内の要素をすべて合計にするにはCollectors#summingXxx
を使用します。
int型の場合はCollectors#summingInt
を使い、Double型の場合はCollectors#summingDouble
を使用します。
Java
Integer result = foodList
.stream()
.collect(Collectors.summingInt(food::getPrice));
System.out.println(result);
実行結果
2770
すべて合計すると90+130+200+100+150+200+500+80+50+1000+150+120=2770になります。
ストリーム内の要素をグループ別に合計する
グループ別に合計を求めたい場合はまずCollectors.groupingBy
でグループ化してからCollectors.summingXxx
で合計を求めます。
Java
Map<String, Integer>result = foodList
.stream()
.collect(Collectors.groupingBy(food::getgroup,
Collectors.summingInt(food::getPrice)));
System.out.println(result);
実行結果
{お菓子=1400, 野菜=420, フルーツ=950}
これで、お菓子、野菜、フルーツのそれぞれのグループで合計を求めることが出来ました。
ストリーム内のすべての要素から最大値を取得する
ストリーム内のすべての要素から最大値を取得するにはCollectors.maxBy
を使用します。
Java
Optional<food> result = foodList
.stream()
.collect(Collectors.maxBy(Comparator.comparing(food::getPrice)));
result.ifPresent(s -> System.out.println(s));
実行結果
ケーキ:1000:お菓子
要素の中でpriceが最大値なのはケーキなので、無事取得できました。
ストリーム内の要素からグループ別に最大値を取得する
グループ別に最大値を求めたい場合はまずCollectors.groupingBy
でグループ化してからCollectors.maxBy
で最大値を求めます。
Java
Map<String, Optional<food>>result = foodList
.stream()
.collect(Collectors.groupingBy(food::getgroup,
Collectors.maxBy(Comparator.comparing(food::getPrice))));
for(Optional<food> map : result.values()) {
map.ifPresent(s -> System.out.println(s));
}
実行結果
ケーキ:1000:お菓子
ブロッコリー:200:野菜
イチゴ:500:フルーツ
これで、お菓子、野菜、フルーツのそれぞれのグループから最大値を持つ要素を取得することが出来ました。
ストリーム内のすべての要素から最小値を取得する
ストリーム内のすべての要素から最小値を取得するにはCollectors.minBy
を使用します。
Java
Optional<food> result = foodList
.stream()
.collect(Collectors.minBy(Comparator.comparing(food::getPrice)));
result.ifPresent(s -> System.out.println(s));
実行結果
アメ:50:お菓子
要素の中でpriceが最大値なのはアメなので、無事取得できました。
ストリーム内の要素からグループ別に最小値を取得する
グループ別に最小値を求めたい場合はまずCollectors.groupingBy
でグループ化してからCollectors.minBy
で最小値を求めます。
Java
Map<String, Optional<food>>result = foodList
.stream()
.collect(Collectors.groupingBy(food::getgroup,
Collectors.minBy(Comparator.comparing(food::getPrice))));
for(Optional<food> map : result.values()) {
map.ifPresent(s -> System.out.println(s));
}
実行結果
アメ:50:お菓子
キャベツ:90:野菜
リンゴ:100:フルーツ
これで、お菓子、野菜、フルーツのそれぞれのグループから最小値を持つ要素を取得することが出来ました。
ストリーム内の要素の個数を求める
ストリーム内の要素の個数を求めるにはCollectors.counting
を使用します。
Java
Long result = foodList
.stream()
.collect(Collectors.counting());
System.out.println(result);
実行結果
12
ストリーム内の要素の個数をグループ別に求める
ストリーム内の要素の個数をグループ別に求めるにはCollectors.groupingBy
でグループしてからCollectors.counting
を使用します。
Java
Map<String, Long> result = foodList
.stream()
.collect(Collectors.groupingBy(food::getgroup,
Collectors.counting()));
for(Map.Entry<String, Long> map: result.entrySet()) {
System.out.println(map.getKey() + " : " + map.getValue());
}
実行結果
お菓子 : 5
野菜 : 3
フルーツ : 4
ストリーム内の要素の平均を求める
ストリーム内の要素の平均を求めるにはCollectors.averagingDouble
を使用します。
Java
Double result = foodList
.stream()
.collect(Collectors.averagingDouble(food::getPrice));
System.out.println(result);
実行結果
230.83333333333334
ストリーム内の要素の平均をグループ別に求める
ストリーム内の要素の平均をグループ別に求めるにはCollectors.groupingBy
でグループしてからCollectors.averagingDouble
を使用します。
Java
Map<String, Double> result = foodList
.stream()
.collect(Collectors.groupingBy(food::getgroup,
Collectors.averagingDouble(food::getPrice)));
for(Map.Entry<String, Double> map: result.entrySet()) {
System.out.println(map.getKey() + " : " + map.getValue());
}
実行結果
お菓子 : 280.0
野菜 : 140.0
フルーツ : 237.5
以上で記事の解説はお終い!
もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!