Java8 Stream

生成処理

streamインスタンス

配列から

Stream<String> stream1 = Stream.of("A", "B", "C", "D", "E");

Stream<String> stream2 = Arrays.stream(new String[] {"A", "B", "C", "D", "E"});

Listから

List<String> list = Arrays.asList("A","B","C","D","E");
Stream<String> stream3 = list.stream();

Mapから

Stream<Entry<String, Double>> map = exp.entrySet().stream();

数値範囲から

IntStream stream = IntStream.range(1, 5);
stream.forEach( System.out::print );
1 2 3 4

IntStream stream = IntStream.rangeClosed(1, 5);
stream.forEach( System.out::print );
1 2 3 4 5

直接中間操作、終端操作

通常はsteramインスタンス変数を作成せず、この方法を用いる
Arrays.asList("A","B","C","D","E").stream().forEach( ~ )

中間操作

map/flatMap

map

各要素に特定の処理を行う

Function型メソッドを介する

List<String> list = Arrays.asList("A","B","C","D","E");

List<String> newList = new ArrayList<>();
for (String s : list) {
 s = s + "+";
 newList.add(s);
}
[A+, B+, C+, D+, E+]

List<String> newList = new ArrayList<>();
list.stream()
 .map(s -> s + "+")
 .forEach(s -> newList.add(s));
[A+, B+, C+, D+, E+]

flatMap

public class Language { 
 private String name;
 private int exp;
 public Language(String name, int exp) {
  this.name = name;
  this.exp = exp;
 }
}

public class Group{
 private List<Language> students = new ArrayList<>();
 public List<Language> getStudents() {
  return this.students;
 }
 public void addStudent(Language students) {
  this.students.add(students);
 }
}

List<Group> groupList = new ArrayList<>();
   
Group group1 = new Group();
group1.addStudent(new Language("Java", 3));
group1.addStudent(new Language("VB.NET", 4));
group1.addStudent(new Language("C#", 2));
group1.addStudent(new Language("VB6", 2));

Group group2 = new Group();
group2.addStudent(new Language("php", 2));
group2.addStudent(new Language("python", 1));

groupList.add(group1);
groupList.add(group2);

List<List<Language>> map = groupList.stream().map(s -> s.getStudents())
 .collect(Collectors.toList());
List<List<Language>>
└[0]
 └Language
  └name:Java
  └exp:3
 └Language
  └ ~
 └Language
  └ ~
 └Language
  └ ~
└[1]
 └Language
  └name:php
  └exp:2
 └Language
  └ ~

List<Language> flatMap = groupList.stream().flatMap(s -> s.getStudents().stream())
 .collect(Collectors.toList());
List<Language>
└Language
 └name:Java
 └exp:3
└Language
 └ ~
└Language
 └ ~
└Language
 └ ~
└Language
 └name:php
 └exp:2
└Language
 └ ~

mapToInt

OptionalInt min = Arrays.asList(“Java”, “PHP”, “C#”).stream()
 .mapToInt(x -> x.length()).min();
min.getAsInt():2

OptionalInt max = Arrays.asList(“Java”, “PHP”, “C#”).stream()
 .mapToInt(x -> x.length()).max();
max.getAsInt():4

filter

条件を満たす要素を選別

Predicate型メソッドを介する
※Predicateがtrueを返す

Integer[] list = {1, 2, 3, 4, 5, 6 };

Predicate<Integer> isThree = (i) -> { return i % 3 == 0; };
lists.stream()
 .filter(isThree)
 .forEach(System.out::println);
→ 3 6

まとめて書いた場合
Arrays.stream(list).filter((i) -> { return i % 3 == 0; }).forEach(System.out::println);

limit

List<String> list = Arrays.asList("A","B","C","D","E");

List<String> newList = new ArrayList<>();
list.stream()
 .limit(3)
 .forEach(s -> newList.add(s));
[A, B, C]

sorted

List<String> list = Arrays.asList("E","D","C","B","A");

List<String> newList = new ArrayList<>();
list.stream()
 .sorted()
 .forEach(s -> newList.add(s));
[E, D, C, B, A]

終端操作

forEach

Stream

List<String> language = Arrays.asList("Java", "C#", "PHP", "Python");

language.stream().forEach( s -> {
 System.out.println(s);
});
Java C# PHP Python

Map

Map<String, Integer> exp = new HashMap<>();
exp.put("Java", 3);
exp.put("C#", 2);
exp.put("PHP", 3);
exp.put("Python", 1);

exp.forEach((key, value) -> {
 System.out.println(key + ":" + value);
});
C#:2 Java:2 PHP:1 Python:1

collect

Collectors.toList

Listへ変換

List<String> list = Arrays.asList("E","D","C","B","A");

List<String> newList =
list.stream()
 .sorted()
 .collect(Collectors.toList());
[E, D, C, B, A]

Collectors.joining

文字列として結合

String s =
 list.stream()
 .sorted()
 .collect(Collectors.joining());
ABCDE

Collectors.groupingBy

集約

List<Language> languages = new ArrayList<>();

languages.add(new Language("Java", 3));
languages.add(new Language("C#", 2));
languages.add(new Language("php", 2));
languages.add(new Language("python", 1));

戻り値はMap型
Map<Integer, List<Language>> map = languages.stream().collect(Collectors.groupingBy(i -> i.getExp()));
Map<Integer, List<Language>>
└[0]
 └key:1
 └value
  └Language
   └name:Java
   └exp:3
└[1]
 └key:2
 └value
  └Language
   └name:PHP
   └exp:2
  └Language
   └ ~
  PHPとC#が集約される
└[2]
 └key:3
 └value
  └Language
   └ ~

集約したListから値を取得
List<Language> list = map.get(2);
List<Language>
Language
 └name:PHP
 └exp:2
Language
 └name:C#
 └exp:2

Collectors.counting

List<String> language = Arrays.asList("Java", "C#", "PHP", "C#", "Python", "Java");

language内の要素で集約、同値の要素数を取得
Map<String, Long> counter = language.stream().collect(Collectors.groupingBy(s -> s, Collectors.counting()));

counter.forEach((key, value) -> {
 System.out.println(key + ":" + value);
});
C#:2 Java:2 PHP:1 Python:1

Match

anyMatch

List<String> list = Arrays.asList("A", "B", "C", "D", "E");
Boolean isMatch = list.stream().anyMatch(s -> s.equals("C"));
isMatch:true

Boolean isMatch = list.stream().anyMatch(s -> s.equals("Z"));
isMatch:false

allMatch

List<String> list = Arrays.asList("A", "B", "C", "D", "E");
Boolean isMatch = list.stream().allMatch(s -> s.length() == 1 );
isMatch:true

Boolean isMatch = list.stream().allMatch(s -> s.length() == 2 );
isMatch:false

noneMatch

List<String> list = Arrays.asList("A", "B", "C", "D", "E");
Boolean isExist = list.stream().noneMatch(s -> s.equals("Z"));
isExist:true

Boolean isExist = list.stream().noneMatch(s -> s.equals("C"));
isExist:false

抽出

findFirst

Optional<Integer> list = Arrays.asList(1, 2, 3, 5, 6).stream().findFirst();
list.get():1

findAny

Optional<Integer> list = Arrays.asList(1, 2, 3, 5, 6).stream().findAny();
list.get():1

min

Optional<Integer> list = Arrays.asList(1, 2, 3, 5, 6).stream().min(Comparator.naturalOrder());
list.get():1

max

Optional<Integer> list = Arrays.asList(1, 2, 3, 5, 6).stream().max(Comparator.naturalOrder());
list.get():6

集計

count

long ret = Arrays.asList(1,2,3,5,7).stream().mapToInt(x -> x).count();
ret:5

sum

int ret = Arrays.asList(1, 2, 3, 5, 6).stream().mapToInt(x -> x).sum();
ret:17

average

OptionalDouble ret = Arrays.asList(1, 2, 3, 5, 6).stream().mapToInt(x -> x).average();
ret.getAsDouble():3.4

Follow me!