[Java11] Stream 使い方まとめ -基本編-

- [[Java11] Stream まとめ -Streamによるメリット-](https://qiita.com/nabekou29/items/360506a8c4ced0bfdba0)
- [Java11] Stream 使い方まとめ -基本編-

## はじめに

Javaを書いて2年ほど経ちまして、最近ではJava11で実装をしています。Java8から9,10を経て[Stream](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html)や[Optional](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Optional.html)にもいくつかのメソッドが追加されています。
現在の開発ではOptionalを本格的に取り入れたりと、Stream,Optionalをより有効に活用できる環境になりました。

それとは別に「これってStreamで書けますか？」「ここStreamで書きたいんですけど...」と聞かれることも多かったり...
他の人のコードを見て、Streamだったらもっと綺麗に書けるのにと思ったり...

いずれにしろもっと積極的にStreamで書いて欲しい!（なぜStreamで書いて欲しいのかは[こちら](https://qiita.com/nabekou29/items/360506a8c4ced0bfdba0)）

ちなみに公式リファレンスを抵抗なく読める人は、今回の記事は役に立たないかもしれません。


## 注意書き

- 本記事はJava11の仕様に基づいて書いています
- 全てのメソッドを網羅しているわけではありません
- わかりやすいように1操作ごとに変数に置いていますが、実際は1文で書くことが好ましいです
- また、中間操作では各操作後のStreamの中身の変化をコメントで表していますが、実際は終端操作をするまでは中間操作は行われないことに留意してください

# 本編

特によく使うものには「⭐️」を付けています。

<details>
<summary>Widgetクラスの想定</summary>
<div>

```java
class Widget {
    private Color color;
    
    private int weight;
    
    private String text;
    
    private List<Widget> childWeights = new ArrayList<>();
    
    public Widget(Color color, int weight) {
        this.color = color;
        this.weight = weight;
    }
    
    public Widget(Color color, int weight, String text) {
        this(color, weight);
        this.text = text;
    }
    
    public Color getColor() {
        return color;
    }
    
    public int getWeight() {
        return weight;
    }
    
    public Optional<String> getText() {
        return Optional.ofNullable(text);
    }
    
    public List<Widget> getChildWeights() {
        return childWeights;
    }
    
    public void setChildWeights(List<Widget> childWeights) {
       this.childWeights = childWeights;
    }
    
    public boolean isColorRed() {
        return color == RED;
    }
    
    public boolean isColorBlue() {
        return color == BLUE;
    }
    
    @Override
    public String toString() {
        return "Widget {color: " + color + ", weigth: " + weight + "}";
    }
    
    @Override
    public boolean equals(Object o) {
        Widget w = (Widget) o;
        return this.color == w.color && this.weight == w.weight;
    }
}
```
</div>
</details>

## Streamの生成

### ⭐️ List・Set・Mapから

- [Collection::stream](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Collection.html#stream())

1番使う方法

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

// Listから
List<Widget> list = List.of(a, b, c); // [a, b, c]
Stream<Widget> listToStream = list.stream(); // <a, b, c>
// Setから
Set<Widget> set = Set.of(a, b, c); // {a, b, c}
Stream<Widget> setToStream = set.stream(); // <a, b, c>
// Mapから
Map<Long, Widget> map = Map.of(1L, a, 2L, b, 3L, c); // {1L : a, 2L : b, 3L : c}
Stream<Long> mapKeyToStream = map.keySet().stream(); // <1L, 2L, 3L>
Stream<Widget> mapValueToStream = map.values().stream(); // <a, b, c>
Stream<Entry<Long, Widget>> mapToStream = map.entrySet().stream(); // <{1L : a}, {2L : b}, {3L : c}>
```

- [Collection::parallelStream](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Collection.html#parallelStream())

最初から並列にしたいとき

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

// Listから
List<Widget> list = List.of(a, b, c); // [a, b, c]
Stream<Widget> listToStream = list.parallelStream(); // <a, b, c>
// Setから
Set<Widget> set = Set.of(a, b, c); // {a, b, c}
Stream<Widget> setToStream = set.parallelStream(); // <a, b, c>
// Mapから
Map<Long, Widget> map = Map.of(1L, a, 2L, b, 3L, c); // {1L : a, 2L : b, 3L : c}
Stream<Long> mapKeyToStream = map.keySet().parallelStream(); // <1L, 2L, 3L>
Stream<Widget> mapValueToStream = map.values().parallelStream(); // <a, b, c>
Stream<Entry<Long, Widget>> mapToStream = map.entrySet().parallelStream(); // <{1L : a}, {2L : b}, {3L : c}>
```

### 配列から
- [Arrays::stream](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Arrays.html#stream(T%5B%5D))

```java
Widget[] arr = {a, b, c};
Stream<Widget> arrayToStream = Arrays.stream(arr); // <a, b, c>
```

### いくつかの値から
#### 1個
- [Stream::of](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#of(T))

```java
Stream<Long> stream1 = Stream.of(100L); // <100L>

// × エラー
Stream<Long> stream2 = Stream.of(null); // <null> ?
```

#### 2..N個
- [Stream::of](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#of(T...))

```java
Stream<Long> stream1 = Stream.of(100L, 200L); // <100L, 200L>
Stream<String> stream2 = Stream.of("A", "B", "C", null); // <"A", "B", "C", null>

Stream<Long> stream3 = Stream.of(null, null); // <null, null>
```

#### 0..1個

- [Stream::ofNullable](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#ofNullable(T))
- [Stream::empty](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#empty())

```java
Stream<Long> stream1 = Stream.ofNullable(100L); // <100L>

Stream<Long> stream2 = Stream.ofNullable(null); // <>
Stream<Long> stream3 = Stream.empty(); // <>
```

### 複数のStreamから
#### ⭐️ 2個のStreamから

- [Stream::concat​](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#concat(java.util.stream.Stream,java.util.stream.Stream))

```java
Stream<Widget> stream1 = Stream.of(a, b, c); // <a, b, c>
Stream<Widget> stream2 = Stream.of(x, y, z); // <x, y, z>
Stream<Widget> stream3 = Stream.concat(stream1, stream2); // <a, b, c, x, y, z>
```

#### 3..N個のStreamから
- [Stream::flatMap](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#flatMap(java.util.function.Function))

使ったことはないですが、いざと言うときはこのように書けます

```java
Stream<Widget> stream1 = Stream.of(a, b); // <a, b>
Stream<Widget> stream2 = Stream.of(c, d); // <c, d>
Stream<Widget> stream3 = Stream.of(e, f); // <e, f>
Stream<Widget> stream4 = Stream.of(g, h); // <g, h>
Stream<Stream<Widget>> stream5_1 = Stream.of(stream1, stream2, stream3, stream4); // <<a, b>, <c, d>, <e, f>, <g, h>>
Stream<Widget> stream5_2 = stream5_1.flatMap(UnaryOperator.identity()); // <a, b, c, d, e, f, g, h>
```

### 整数の特定の範囲から(IntStream)

- [IntStream::range](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/IntStream.html#range(int,int))
- [IntStream::rangeClosed](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/IntStream.html#rangeClosed(int,int))

```java
IntStream stream1To4 = IntStream.range(1, 5); // IntStream<1, 2, 3, 4>
IntStream stream1To5 = IntStream.rangeClosed(1, 5); // IntStream<1, 2, 3, 4, 5>
```

## 中間操作

### ⭐️ マッピング
#### 1 : 1 変換

- [Stream::map​](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#map(java.util.function.Function))

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

// Widget -> Color
Stream<Widget> stream1_1 = Stream.of(a, b, c); // <a, b, c>
Stream<Color> stream1_2 = stream1_1.map(Widget::getColor); // <RED, RED, BLUE>

// Widget -> 重さ(int)
Stream<Widget> stream2_1 = Stream.of(a, b, c); // <a, b, c>
Stream<Integer> stream2_2 = stream2_1.map(Widget::getWeight); // <10, 15, 20>

// number -> number * 2
IntStream stream3_1 = IntStream.range(1, 5); // IntStream<1, 2, 3, 4>
IntStream stream3_2 = stream3_1.map(i -> i * 2); // IntStream<2, 4, 6, 8>
```

#### 1 : 0..N 変換

- [Stream::flatMap​](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#flatMap(java.util.function.Function))

```java
Widget a = new Widget(RED, 10);
Widget a_1 = new Widget(RED, 1);
Widget a_2 = new Widget(RED, 2);
Widget a_3 = new Widget(RED, 4);
a.setChildWeights(List.of(a_1, a_2, a_3));
Widget b = new Widget(RED, 15);
Widget b_1 = new Widget(RED, 8);
b.setChildWeights(List.of(b_1));
Widget c = new Widget(BLUE, 20);

// Widget -> それぞれの子Widget
Stream<Widget> stream1 = Stream.of(a, b, c); // <a, b, c>
Stream<List<Widget>> stream2 = stream1.map(Widget::getChildWeights); // <[a_1, a_2, a_3], [b_1], []>
Stream<Widget> stream3 = stream2.flatMap(Collection::stream); // <a_1, a_2, a_3, b_1>
```

#### 1 : 0..1 変換

- [Stream::flatMap​](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#flatMap(java.util.function.Function))
- [Optional::stream](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Optional.html#stream())

```java
Widget a = new Widget(RED, 10, "A");
Widget b = new Widget(RED, 15, "B");
Widget c = new Widget(BLUE, 20);

// Widget -> text(String)
Stream<Widget> stream1 = Stream.of(a, b, c); // <a, b, c>
Stream<Optional<String>> stream2 = stream1.map(Widget::getText); // <<"A">, <"B">, <>>
Stream<String> stream3 = stream2.flatMap(Optional::stream); // <"A", "B">
```

### Stream\<T\>からIntStreamなど

- [Stream::mapToInt](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#mapToInt(java.util.function.ToIntFunction))

```java
Stream<Integer> stream1_1 = Stream.of(1, 2, 3, 4); // <1, 2, 3, 4>
IntStream stream1_2 = stream1_1.mapToInt(i -> i); // IntStream<1, 2, 3, 4>
```

### IntStreamなどからStream\<Integer\>など

```java
IntStream stream1_1 = IntStream.range(1, 5); // IntStream<1, 2, 3, 4>
Stream<Integer> stream1_2 = stream1_1.boxed(); // <1, 2, 3, 4>

IntStream stream2_1 = IntStream.range(1, 5); // IntStream<1, 2, 3, 4>
Stream<String> stream2_2 = stream2_1.mapToObj(i -> String.valueOf(i)); // <"1", "2", "3", "4">
```

### ⭐️ フィルター

- [Stream::filter](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#filter(java.util.function.Predicate))
- [Predicate::not](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/function/Predicate.html#not(java.util.function.Predicate))
- [Predicate::isEqual](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/function/Predicate.html#isEqual(java.lang.Object))
- [Predicate::or](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/function/Predicate.html#or(java.util.function.Predicate))

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);
Widget d = new Widget(GREEN, 25);

// 赤色のものを抽出
Stream<Widget> stream1_1 = Stream.of(a, b, c, d); // <a, b, c, d>
Stream<Widget> stream1_2 = stream1_1.filter(Widget::isColorRed); // <a, b>
// 重さが10より大きいものを抽出
Stream<Widget> stream1_3 = Stream.of(a, b, c, d); // <a, b, c, d>
Stream<Widget> stream1_4 = stream1_3.filter(w -> w.getWeight() > 10); // <b, c, d>

// 赤色でないものを抽出(1)
Stream<Widget> stream2_1 = Stream.of(a, b, c, d); // <a, b, c, d>
Stream<Widget> stream2_2 = stream2_1.filter(w -> !w.isColorRed()); // <c, d>
// 赤色でないものを抽出(2)
Stream<Widget> stream2_3 = Stream.of(a, b, c, d); // <a, b, c, d>
Stream<Widget> stream2_4 = stream2_2.filter(Predicate.not(Widget::isColorRed)); // <c, d>

// 等価のものを抽出(1)
Stream<Widget> stream3_1 = Stream.of(a, b, c, d, null); // <a, b, c, d, null>
Stream<Widget> stream3_2= stream3_1.filter(w -> Objects.equals(w, new Widget(RED, 15))); // <b>
// 等価のものを抽出(2)
Stream<Widget> stream3_3 = Stream.of(a, b, c, d, null); // <a, b, c, d, null>
Stream<Widget> stream3_4= stream3_3.filter(Predicate.isEqual(new Widget(RED, 15))); // <b>

// 赤色か青色のものを抽出(1)
Stream<Widget> stream4_1 = Stream.of(a, b, c, d); // <a, b, c, d>
Stream<Widget> stream4_2 = stream4_1.filter(w -> w.isColorRed() || w.isColorBlue()); // <a, b, c>
// 赤色か青色のものを抽出(2)
Stream<Widget> stream4_3 = Stream.of(a, b, c, d); // <a, b, c, d>
Predicate<Widget> isColorRed = Widget::isColorRed; 
// Widget::isColorRedがPredicateである保証がないため
// filter((Widget::isColorRed).or(Widget::isColorBlue))とは書けない
Stream<Widget> stream4_4 = stream4_2.filter(isColorRed.or(Widget::isColorBlue)); // <a, b, c>
```

### 重複除去(distinct)

- [Stream::distinct](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#distinct())

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);

Stream<Widget> stream1_1 = Stream.of(a, a, b, b, null, null); // <a, a, b, b, null, null>
Stream<Widget> stream1_2 = stream1_1.distinct(); // <a, b, null>
```

### ⭐️ ソート

- [Stream::sorted](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#sorted())

```java

Widget a = new Widget(RED, 10, "A");
Widget b = new Widget(RED, 15, "B");
Widget c = new Widget(BLUE, 20);
Widget d = new Widget(GREEN, 25;

// 重さでソート
Stream<Widget> stream1_1 = Stream.of(b, c, a); // <b, c, a>
Stream<Widget> stream1_2 = stream1_1.sorted(Comparator.comparing(Widget::getWeight)); // <a, b, c>

// 重さでソート(降順)
Stream<Widget> stream2_1 = Stream.of(b, c, a); // <b, c, a>
Stream<Widget> stream2_2 = stream2_1.sorted(Comparator.comparing(Widget::getWeight, Comparator.reverseOrder())); // <c, b, a>

// テキストでソート(nullを最初にする)
Stream<Widget> stream3_1 = Stream.of(b, c, a); // <b, c, a>
Stream<Widget> stream3_2 = stream3_1.sorted(Comparator.comparing(w -> w.getText().orElse(null), Comparator.nullsFirst(Comparator.naturalOrder()))); <c, a, b>

// 第一ソート: 赤色か, 第二ソート: 重さ
Stream<Widget> stream4_1 = Stream.of(b, c, a, d); // <b, c, a, d>
Stream<Widget> stream4_2 = stream4_1.sorted(Comparator.comparing(Widget::isColorRed).thenComparing(Widget::getWeight)); // <c, d, a, b>
```

### 最初のN個

- [Stream::limit](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#limit(long))

```java
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5); // <1, 2, 3, 4, 5>
Stream<Integer> stream2 = stream1.limit(3); // <1, 2, 3>
```

### 最初のN個以外

- [Stream::skip](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#skip(long))

```java
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5); // <1, 2, 3, 4, 5>
Stream<Integer> stream2 = stream1.skip(2); // <3, 4, 5>
```

## 終端操作

### ⭐️ Listを作成

- [Stream::collect](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#collect(java.util.stream.Collector))
- [Collectors::toList](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Collectors.html#toList())

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

Stream<Widget> stream = Stream.of(a, b, c); // <a, b, c>
List<Widget> list = stream.collect(Collectors.toList()); // [a, b, c]
```

### Setを作成

- [Stream::collect](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#collect(java.util.stream.Collector))
- [Collectors::toSet](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Collectors.html#toSet())

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

Stream<Widget> stream = Stream.of(a, b, c); // <a, b, c>
Set<Widget> set = stream.collect(Collectors.toSet()); // {a, b, c}
```

### ⭐️ Mapを作成

- [Stream::collect](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#collect(java.util.stream.Collector))
- [Collectors::toMap](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Collectors.html#toMap(java.util.function.Function,java.util.function.Function))
- [Collectors::groupingBy](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Collectors.html#groupingBy(java.util.function.Function))

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

Stream<Widget> stream1 = Stream.of(a, b, c); // <a, b, c>
Map<Integer, Color> map1 = stream.collect(Collectors.toMap(Widget::getWeight, Widget::getColor)); // {10: RED, 15: RED, 20: BLUE}

Stream<Widget> stream2_1 = Stream.of(a, b, c); // <a, b, c>
Map<Color, Widget> map2_1 = stream.collect(Collectors.toMap(Widget::getColor, UnaryOperator.identity(), (w1, w2) -> w1)); // {RED: a, BLUE: c}
Stream<Widget> stream2_2 = Stream.of(a, b, c); // <a, b, c>
Map<Color, Widget> map2_2 = stream.collect(Collectors.toMap(Widget::getColor, UnaryOperator.identity(), (w1, w2) -> w2)); // {RED: b, BLUE: c}
// × エラー (キーが衝突する場合は先の方と後の方のどちらを優先するかを指定する必要がある)
Stream<Widget> stream2_3 = Stream.of(a, b, c); // <a, b, c>
Map<Color, Widget> map2_3 = stream.collect(Collectors.toMap(Widget::getColor, UnaryOperator.identity())); 

Stream<Widget> stream3 = Stream.of(a, b, c); // <a, b, c>
Map<Color, List<Widget>> map3 = stream3.collect(Collectors.groupingBy(Widget::getColor)); // {RED: [a, b], BLUE: [c]}
```

### ⭐️ 繰り返し処理(forEach)

- [Stream::forEach](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#forEach(java.util.function.Consumer))

```java
Stream<Integer> stream = Stream.of(1, 2, 3); // <1, 2, 3>
stream.forEach(System.out::println);
// 標準出力:
// 1
// 2
// 3
```

### 要素数を取得

- [Stream::count](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#count())

```java
Stream<Integer> stream = Stream.of(1, 2, 3); // <1, 2, 3>
long cnt = stream.count(); // 3L
```

### ⭐️ 文字列を結合

- [Stream::count](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#count())
- [Collectors::joining](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Collectors.html#joining())

```java
Stream<Widget> stream1 = Stream.of("A", "B", "C"); // <"A", "B", "C">
String str1 = stream1.collect(Collectors.joining()); // "ABC"

Stream<Widget> stream2 = Stream.of("A", "B", "C"); // <"A", "B", "C">
String str2 = stream2.collect(Collectors.joining(", ")); // "A, B, C"

Stream<Widget> stream3 = Stream.of("A", "B", "C"); // <"A", "B", "C">
String str3 = stream3.collect(Collectors.joining(", ", "[", "]")); // "[A, B, C]"
```

### 数値の合計を取得

- [IntStream::sum](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#count())
- [Collectors::summingInt](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Collectors.html#summing())

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

Stream<Widget> stream1_1 = Stream.of(a, b, c); // <a, b, c>
IntStream stream1_2 = stream1_1.mapToInt(Widget::getWeight); // <10, 15, 20>
int sum1 = stream1_2.sum(); // 45

Stream<Widget> stream2_1 = Stream.of(a, b, c); // <a, b, c>
int sum2 = stream2.collect(Collectors.summingInt(Widget::getWeight)); // 45
```

### ⭐️ 最大値を取得
- [Stream::max](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#max(java.util.Comparator))
- [IntStream::max](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/IntStream.html#max())

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

Stream<Widget> stream1 = Stream.of(a, b, c); // <a, b, c>
Optional<Widget> widget = stream1.max(Comparator.comparing(Widget::getWeight)); // <c>

Stream<Widget> stream2_1 = Stream.of(a, b, c); // <a, b, c>
IntStream stream2_2 = stream2_1.mapToInt(Widget::getWeight); // <10, 15, 20>
OptionalInt max = stream2_2.max(); // <20>
```

### ⭐️ 最小値を取得

- [Stream::min](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#min(java.util.Comparator))
- [IntStream::min](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/IntStream.html#min())

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

Stream<Widget> stream1 = Stream.of(a, b, c); // <a, b, c>
Optional<Widget> widget = stream1.min(Comparator.comparing(Widget::getWeight)); // <a>

Stream<Widget> stream2_1 = Stream.of(a, b, c); // <a, b, c>
IntStream stream2_2 = stream2_1.mapToInt(Widget::getWeight); // <10, 15, 20>
OptionalInt min = stream2_2.min(); // <10>
```

### ⭐️ 最初の要素を取得

- [Stream::findFirst](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#findFirst())

```java
Stream<Integer> stream = Stream.of(1, 2, 3); // <1, 2, 3>
Optional<Integer> n = stream.findFirst() // <1>
```

### ⭐️ 任意の要素を取得

- [Stream::findAny](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#findAny())

```java
Stream<Integer> stream = Stream.of(1, 2, 3); // <1, 2, 3>
Optional<Integer> n = stream.findAny() // <1>
```

### ⭐️ 真偽値を返す

#### 任意の1つ以上の要素が条件に合う

- [Stream::anyMatch](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#anyMatch(java.util.function.Predicate))

```java
Widget a = new Widget(RED, 10);
Widget b = new Widget(RED, 15);
Widget c = new Widget(BLUE, 20);

Stream<Widget> stream1 = Stream.of(a, b, c); // <a, b, c>
boolean bool1 = stream1.anyMatch(Widget::isColorRed); // true

Stream<Widget> stream2 = Stream.of(c); // <c>
boolean bool2 = stream2.anyMatch(Widget::isColorRed); // false

Stream<Widget> stream3 = Stream.of(); // <>
boolean bool3 = stream3.anyMatch(Widget::isColorRed); // false
```

#### 全ての要素が条件に合う

- [Stream::allMatch](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#allMatch(java.util.function.Predicate))

Streamが空の場合の挙動に注意

```java
Stream<Widget> stream1 = Stream.of(a, b); // <a, b>
boolean bool1 = stream1.allMatch(Widget::isColorRed); // true

Stream<Widget> stream2 = Stream.of(b, c); // <b, c>
boolean bool2 = stream2.allMatch(Widget::isColorRed); // false

Stream<Widget> stream3 = Stream.of(); // <>
boolean bool3 = stream3.allMatch(Widget::isColorRed); // true
```

#### 全ての要素が条件に合わない

- [Stream::noneMatch](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/stream/Stream.html#noneMatch(java.util.function.Predicate))

Streamが空の場合の挙動に注意

```java
Stream<Widget> stream1 = Stream.of(c); // <c>
boolean bool1 = stream1.noneMatch(Widget::isColorRed); // true

Stream<Widget> stream2 = Stream.of(b, c); // <a, b, c>
boolean bool2 = stream2.noneMatch(Widget::isColorRed); // false

Stream<Widget> stream3 = Stream.of(); // <>
boolean bool3 = stream3.noneMatch(Widget::isColorRed); // true
```