Java Stream API まとめ

n-ozawan

峻さん、こんにちは。晦永蝕�kグル�`プの稼-看噛温敬温稼です。
噴方定ぶりに永遺を徭恬しました。劣と書とでは���爐�呟なり屯戯湊隻彜蓑でした。迦中と念中をガラスで嶄附がスケスケなピラ�`レス永遺ケ�`スが恷除のトレンドのようです。

云籾です。
謹くの冱�Zでは塘双などの秤�鵑魴����I尖するためのメソッドが並念に喘吭されていることが謹いです。Javaも箭翌ではなく、Java 8 からStream APIが弖紗され、ラムダ塀を聞った郡���I尖ができるようになりました。書指はJavaのStream APIで採ができるのかをまとめたいと房います。

Stream API

はじめに

JavaのStream APIは、コレクションや塘双などのデ�`タを傚冱議に�I尖するための�C嬬で、愔瓦任△譴�for猟で��峰したコ�`ドを、より岷湖議で辛�i來互くコ�`ディングすることができます。

箭えば仝儲々が原く兆念を渇竃したい魁栽、愔瓦隆擺念�猟では參和のように芝峰します。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
List<String> filteredNames = new ArrayList<>();
for (String name : names) {
  if (name.contains("儲")) {
    filteredNames.add(name);
  }
}
IO.println(filteredNames);    // [恃儲, 卅儲]

Stream APIを聞うと參和のようになります。愔瓦離芥`ドでは、採をしたい�I尖なのかを尖盾するのに、コ�`ドを�iみ�zむ駅勣がありました。しかし、Stream APIではfilterやcollectなどの冱匐から、採をしたい�I尖なのかがはっきりと蛍かるようになります。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
List<String> filteredNames = names.stream()
  .filter(name -> name.contains("儲"))
  .collect(Collectors.toList());
IO.println(filteredNames);    // [恃儲, 卅儲]

Stream API は寄きく3つのフェ�`ズに蛍かれます。

  • 皆岳姻艶温馨の蝕兵
  • 嶄寂荷恬
  • 嶮極荷恬

皆岳姻艶温馨の蝕兵

皆岳姻艶温馨を蝕兵するには、皆岳姻艶温馨インスタンスを恬撹する駅勣があります。晦庄壊岳や皆艶岳などであればstream()メソッドを柵び竃すことで皆岳姻艶温馨を蝕兵することができます。珂温沿は遺看鉛鉛艶界岳庄看稼ではありませんので、岷俊stream()メソッドを柵び竃すことはできませんが、entrySet()メソッドで皆艶岳を函誼することで皆岳姻艶温馨を蝕兵することができます。塘双の魁栽はArrays.stream()を聞喘します。

// Listの��栽
List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
Stream<String> nameStream = names.stream();

// Setの��栽
Set<String> nameSet = Set.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
Stream<String> nameStreamFromSet = nameSet.stream();

// Mapの��栽
Map<String, Integer> nameAgeMap = Map.ofEntries(
  Map.entry("恃儲", 30),
  Map.entry("�椳", 25),
  Map.entry("互��", 28),
  Map.entry("弥嶄", 22),
  Map.entry("卅儲", 35)
);
Stream<Map.Entry<String, Integer>> nameAgeStream = nameAgeMap.entrySet().stream();

// 塘双の��栽
String[] nameArray = {"恃儲", "�椳", "互��", "弥嶄", "卅儲"};
Stream<String> nameStreamFromArray = Arrays.stream(nameArray);

嶄寂荷恬

嶄寂荷恬はStreamに��して紗垢などを佩い、仟しいStreamを伏撹します。いくつか喘吭されていますが、ここでは麼な嶄寂荷恬を�B初します。

filter()

蒙協の訳周に栽崑する勣殆だけを渇竃します。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
List<String> filteredNames = names.stream()
  .filter(name -> name.contains("儲"))
  .collect(Collectors.toList());
IO.println(filteredNames);    // [恃儲, 卅儲]

map() / flagMap()

�、發靴�は侏を�筝�します。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
List<String> uppercasedNames = names.stream()
  .map(name -> name + "さん")
  .collect(Collectors.toList());
IO.println(uppercasedNames);    // [恃儲さん, �椳さん, 互�鬚気�, 弥嶄さん, 卅儲さん]

distinct()

嶷鹸を��茅します。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲", "恃儲", "卅儲");
List<String> distinctNames = names.stream()
  .distinct()
  .collect(Collectors.toList());
IO.println(distinctNames);    // [恃儲, �椳, 互��, 弥嶄, 卅儲]

sorted()

ソ�`トします。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
List<String> sortedNames = names.stream()
  .sorted()
  .collect(Collectors.toList());
IO.println(sortedNames);    // [卅儲, 恃儲, �椳, 互��, 弥嶄]

嶮極荷恬

嶮極荷恬はStreamの恷瘁に佩われる荷恬です。

forEach()

皆岳姻艶温馨の枠遊から挑極までを乏肝�I尖します。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
names.stream().forEach(name -> IO.println(name));
// 恃儲
// �椳
// 互��
// 弥嶄
// 卅儲

collect()

皆岳姻艶温馨の坪否を遺看鉛鉛艶界岳庄看稼侏�┳⊂渦�岳や皆艶岳��に�篁擦靴泙后�

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
List<String> filteredNames = names.stream()
  .filter(name -> name.contains("儲"))
  .collect(Collectors.toList());
IO.println(filteredNames);    // [恃儲, 卅儲]

麿にもグル�`ピングもできます。參和は兆念の猟忖方ごとにグル�`ピングしています。

List<String> names02 = List.of("恃儲", "�椳匯", "互��", "弥嶄�{", "卅儲", "表", "弌爽", "表弥湊隻");
Map<Integer, List<String>> groupedByLength = names02.stream()
  .collect(Collectors.groupingBy(String::length));
IO.println(groupedByLength);    // {1=[表], 2=[恃儲, 互��, 卅儲, 弌爽], 3=[�椳匯, 弥嶄�{], 4=[表弥湊隻]}

count()

勣殆方を卦抜します。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");
long count = names.stream()
  .filter(name -> name.contains("儲"))
  .count();
IO.println(count);    // 2

reduce()

1つの秤烏に鹿埃します。

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
int sum = numbers.stream()
  .reduce(0, Integer::sum);
IO.println(sum);    // 15

もちろん、リストに鯉追された方�、鮑亘磴垢襪世韻任△譴弌�參和でもできます。

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
int sum2 = numbers.stream()
  .mapToInt(Integer::intValue)
  .sum();
IO.println(sum2);    // 15

anyMatch() / allMatch() / noneMatch()

allMatch()は畠ての勣殆が蒙協の訳周に栽崑すればtrue、栽崑しなければfalseを卦抜します。anyMatch()はどれが1つでも蒙協の訳周に栽崑すればtrue、栽崑しなければfalseを卦抜します。noneMatch()は!anyMatch()と揖じです。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");

// anyMatch
boolean hasSuzuki = names.stream()
  .anyMatch(name -> name.equals("�椳"));
IO.println(hasSuzuki);    // true

// allMatch
boolean allHaveTo = names.stream()
  .allMatch(name -> name.contains("弥"));
IO.println(allHaveTo);    // false

// noneMatch
boolean noneHaveYamamoto = names.stream()
  .noneMatch(name -> name.equals("表云"));
IO.println(noneHaveYamamoto);    // true

旺双�I尖

Stream APIでは旺双�I尖を佩うことができます。旺双�I尖したい��栽は、parallelStream()で皆岳姻艶温馨を蝕兵します。

List<String> names = List.of("恃儲", "�椳", "互��", "弥嶄", "卅儲");

names.parallelStream()
.filter(name -> {
  IO.println("フィルタ嶄: " + name + " - " + Thread.currentThread().getName());
  return name.contains("儲");
})
.map(name -> {
  IO.println("���Q嶄: " + name + " - " + Thread.currentThread().getName());
  return "こんにちは、" + name + "さん";
})
.forEach(name -> IO.println(name));

�Y惚は參和になります。光勣殆が��なるスレッドで旺双�I尖されていることが蛍かります。

フィルタ嶄: 卅儲 - ForkJoinPool.commonPool-worker-3
フィルタ嶄: 恃儲 - ForkJoinPool.commonPool-worker-2
フィルタ嶄: 弥嶄 - ForkJoinPool.commonPool-worker-4
���Q嶄: 卅儲 - ForkJoinPool.commonPool-worker-3
���Q嶄: 恃儲 - ForkJoinPool.commonPool-worker-2
フィルタ嶄: 互�� - main
フィルタ嶄: �椳 - ForkJoinPool.commonPool-worker-1
こんにちは、恃儲さん
こんにちは、卅儲さん

おわりに

仝干温厩温皆界姻庄沿岳での郡���I尖まとめ々でも��きましたが、Stream APIも坪何ではfor猟によるル�`プ�I尖が佩われています。よって�o�jなメソッドチェ�`ンは掲�紳覆��I尖になりますので、聞喘する�Hはその�xりをよく深えて�g廾すると措いでしょう。

ではたま。


Recommendおすすめブログ