Java
java8

Java8 逆引き Stream API


はじめに

Java8の新機能、Stream APIを使い始めてコーディングが格段に楽になりました。

備忘録的にサンプルコードを書き出してみました。少しずつ追加していく予定です。

Javaは使ったことあるけどラムダ式やStream APIはよく知らないという方は、参考にしてみてください。

バリバリ使っている方は、こんな使い方もあるよ!と教えていただけると嬉しいです。

ちなみにオライリー社のJavaによる関数型プログラミング ―Java 8ラムダ式とStreamがとても参考になりました。


【前提条件】Stream APIの説明に使用するオブジェクト


Person.java

public class Person {

private String name;
private int age;
private List<Person> children;

public Person(String name){/*...*/}
public Person(String name, int age){/*...*/}
public Person(String name, int age, Person... children){/*...*/}

@Override
public String toString() {/* name(age) [children...] */}

// getter, setter...
}



コレクション、配列、MapをStreamクラスに変換(Arrays#stream,Stream#of)


Stream.java

  // コレクション

List<String> list = new ArrayList<>();
Stream<String> listStream = list.stream();

// 配列
String[] ary = new String[] {"AA","BB","CC"};
Stream<String> aryStream1 = Arrays.stream(ary);
Stream<String> aryStream2 = Stream.of(ary);

// MAP
Map<String,String> map = new HashMap<>();
Stream<Entry<String, String>> mapStream = map.entrySet().stream();



メソッド参照・コンストラクタ参照(Class::method)


Reference.java

  String[] names = new String[] {"Tom","Bob","Alice"};

Stream.of(names)
// コンストラクタ参照
.map(Person::new) // name -> new Person(name)
// メソッド参照
.forEach(System.out::println); // person -> System.out.println(person)
// Tom(0)
// Bob(0)
// Alice(0)



Personリストからnameリスト作成(Stream#collect,Collectors#toList)


NameList.java

  List<Person> persons = new ArrayList<>();

persons.add(new Person("Tom", 21));
persons.add(new Person("Bob", 25));
persons.add(new Person("Alice",19));

List<String> nameList =
persons.stream()
.map(Person::getName)
.collect(Collectors.toList());

nameList.stream().forEach(System.out::println);
// "Tom"
// "Bob"
// "Alice"



PersonリストからnameのCSV作成(Stream#collect,Collectors#joining)


NameCSV.java

  List<Person> persons = new ArrayList<>();

persons.add(new Person("Tom", 21));
persons.add(new Person("Bob", 25));
persons.add(new Person("Alice",19));

String nameCSV =
persons.stream()
.map(p -> String.format("\"%s\"", p.getName()))
.collect(Collectors.joining(","));

System.out.println(nameCSV);
// "Tom","Bob","Alice"



Personリストからageの重複なしリスト作成(Stream#distinct)


AgeDistinctList.java

  List<Person> persons = new ArrayList<>();

persons.add(new Person("Tom", 21));
persons.add(new Person("Bob", 25));
persons.add(new Person("Alice",19));
persons.add(new Person("Mike", 19));

List<Integer> ageDistinctList =
persons.stream()
.map(Person::getAge)
.distinct()
.collect(Collectors.toList());

ageDistinctList.stream().forEach(System.out::println);
// 21
// 25
// 19



Personリストをage順にソート(Stream#sorted,Comparator#comparingInt)


Sort.java

  List<Person> persons = new ArrayList<>();

persons.add(new Person("Tom", 21));
persons.add(new Person("Bob", 25));
persons.add(new Person("Alice",19));

persons.stream()
.sorted(Comparator.comparingInt(Person::getAge))
.forEach(System.out::println);
// Alice(19)
// Tom(21)
// Bob(25)



Personリストをname頭文字でグループ化(Comparator#groupingBy)


NameIndex.java

  List<Person> persons = new ArrayList<>();

persons.add(new Person("Tom", 21));
persons.add(new Person("John", 18));
persons.add(new Person("Jack", 19));

Map<Object,List<Person>> nameIndex =
persons.stream()
.collect(Collectors.groupingBy(p -> p.getName().charAt(0)));

System.out.println(nameIndex);
// {J=[John(18), Jack(19)], T=[Tom(21)]}



Personリストからchildrenリスト作成(Stream#flatMap)


ChildrenList.java

  List<Person> persons = new ArrayList<>();

persons.add(new Person("Tom", 21,
new Person("Tomas", 1),
new Person("Tommy", 0)));
persons.add(new Person("Bob", 25,
new Person("Bobby", 2)));
persons.add(new Person("Alice", 19));

persons.stream()
.flatMap(person -> person.getChildren().stream())
.forEach(System.out::println);
// Tomas(1)
// Tommy(0)
// Bobby(2)