Java8 逆引き Stream API 

##はじめに
Java8の新機能、Stream APIを使い始めてコーディングが格段に楽になりました。
備忘録的にサンプルコードを書き出してみました。少しずつ追加していく予定です。
Javaは使ったことあるけどラムダ式やStream APIはよく知らないという方は、参考にしてみてください。
バリバリ使っている方は、こんな使い方もあるよ！と教えていただけると嬉しいです。

ちなみにオライリー社の[Javaによる関数型プログラミング ―Java 8ラムダ式とStream](http://amzn.to/2jc4eDG)がとても参考になりました。
<a href="https://www.amazon.co.jp/Java%E3%81%AB%E3%82%88%E3%82%8B%E9%96%A2%E6%95%B0%E5%9E%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-_Java-8%E3%83%A9%E3%83%A0%E3%83%80%E5%BC%8F%E3%81%A8Stream-Venkat-Subramaniam/dp/4873117046/ref=as_li_ss_il?ie=UTF8&qid=1484016396&sr=8-1&keywords=Java%E3%81%AB%E3%82%88%E3%82%8B%E9%96%A2%E6%95%B0%E5%9E%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&linkCode=li1&tag=nesheep5-22&linkId=a80381fa2e7e102520379c5deee46112" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4873117046&Format=_SL110_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=nesheep5-22" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=nesheep5-22&l=li1&o=9&a=4873117046" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

#### 【前提条件】Stream APIの説明に使用するオブジェクト
```java: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)
```java: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)
```java: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)
```java: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)
```java: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)
```java: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)
```java: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)
```java: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)
```java: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)    
```