Java8 Stream API 中間処理 (IntermediateOperation)

java8 Stream APIの中間処理についてのメモです。

前回の続きで、Stream APIの中間処理について書きました。
pppurple.hatenablog.com

ストリーム生成⇒中間処理⇒終端処理の中間処理の部分です。

目次

中間処理

filter

filterはストリームの各要素に対して、条件を指定して要素をフィルタリングします。
perlでのgrepに近い感じです。
引数としてPredicateインターフェースを取るので、booleanを返す関数を記述します。

intでのfilter。
6以上の数でフィルタリング。

    // int
    IntStream.rangeClosed(0, 10)
            .filter(i -> i > 5)
            .forEach(System.out::println);

結果

    6
    7
    8
    9
    10

Stringでのfilter。
文字列の最後がcの要素でフィルタリング。

    // String
    String[] texts = {"aaa", "bbb", "ccc", "abc"};
    Arrays.stream(texts)
            .filter(text -> text.endsWith("c"))
            .forEach(System.out::println);

結果

    ccc
    abc

テストコード

@Test
public void filter() {
    // int
    IntStream.rangeClosed(0, 10)
            .filter(i -> i > 5)
            .forEach(System.out::println);

    List<Integer> intList = IntStream.rangeClosed(0, 10)
            .filter(i -> i > 5)
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).containsOnly(6, 7, 8, 9, 10);

    // String
    String[] texts = {"aaa", "bbb", "ccc", "abc"};
    Arrays.stream(texts)
            .filter(text -> text.endsWith("c"))
            .forEach(System.out::println);

    List<String> strList = Arrays.stream(texts)
            .filter(text -> text.endsWith("c"))
            .collect(Collectors.toList());
    assertThat(strList).containsOnly("ccc", "abc");
}

map

mapはストリームの各要素に対して、指定した関数を適用したストリームを返します。
引数としてFunctionインターフェースを取るので、何らかの型を返す関数を記述します。

intを与えてintで返すmap。
それぞれ数字に10を足して返す。

    // int -> int
    IntStream.rangeClosed(1, 10)
            .map(i -> i + 10)
            .forEach(System.out::println);

結果

    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

Stringを与えてStringを返すmap。
それぞれの文字列を"|"で囲った文字列を返す。

    // String -> String
    String[] texts = {"aaa", "bbb", "ccc"};
    Arrays.stream(texts)
            .map(text -> "|" + text + "|")
            .forEach(System.out::println);

結果

    |aaa|
    |bbb|
    |ccc|

テストコード

@Test
public void map() {
    // int -> int
    IntStream.rangeClosed(1, 10)
            .map(i -> i + 10)
            .forEach(System.out::println);

    List<Integer> intList = IntStream.rangeClosed(1, 10)
            .map(i -> i + 10)
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).containsOnly(11, 12, 13, 14, 15, 16, 17, 18, 19, 20);

    // String -> String
    String[] texts = {"aaa", "bbb", "ccc"};
    Arrays.stream(texts)
            .map(text -> "|" + text + "|")
            .forEach(System.out::println);

    List<String> strList = Arrays.stream(texts)
            .map(text -> "|" + text + "|")
            .collect(Collectors.toList());
    assertThat(strList).containsOnly("|aaa|", "|bbb|", "|ccc|");
}

mapToInt

mapToIntはストリームの各要素に対して、指定した関数を適用したIntStreamを返します。
引数としてToIntFunctionインターフェースを取るので、intを返す関数を記述します。

同様にLongStremを返すmapToLong、DoubleStreamを返すmapToDoubleがあります。

各文字列の文字数を返すmapToInt。

    // Stringからintへ変換
    String[] texts2 = {"aaa", "bbbb", "ccccc"};
    Arrays.stream(texts2)
            .mapToInt(String::length)
            .forEach(System.out::println);

結果

    3
    4
    5

テストコード

@Test
public void mapToInt() {
    // Stringからintへ変換
    String[] texts2 = {"aaa", "bbbb", "ccccc"};
    Arrays.stream(texts2)
            .mapToInt(String::length)
            .forEach(System.out::println);

    List<Integer> stringToInt = Arrays.stream(texts2)
            .mapToInt(String::length)
            .boxed()
            .collect(Collectors.toList());
    assertThat(stringToInt).containsOnly(3, 4, 5);
}

mapToObj

mapToObjはIntStream、LongStream、DoubleStreamの各要素に対して、指定した関数を適用してStreamを返します。
引数としてIntFunctionインターフェースを取るので、intを与えて何らかの型を返す関数を記述します。

mapToIntはIntStream、LongStream、DoubleStreamでそれぞれ定義されています。

数字からyenをつけた文字列を返すmapToObj。

    // intからStringへ変換
    IntStream.rangeClosed(1, 5)
            .mapToObj(i -> i + "yen")
            .forEach(System.out::println);

結果

    1yen
    2yen
    3yen
    4yen
    5yen

テストコード

@Test
public void mapToObj() {
    // intからStringへ変換
    IntStream.rangeClosed(1, 5)
            .mapToObj(i -> i + "yen")
            .forEach(System.out::println);

    List<String> intToString = IntStream.rangeClosed(1, 5)
            .mapToObj(i -> i + "yen")
            .collect(Collectors.toList());
    assertThat(intToString).containsOnly("1yen", "2yen", "3yen", "4yen", "5yen");
}

flatMap

flatMapはmapと同様にストリームの各要素に対して、指定した関数を適用しますが、
適用された各要素を一つの新しいストリームとして返します。

下記の場合、"aaa bbb ccc"と"ddd eee fff"をそれぞれスペースで分割しますが、
普通のmapの場合、"aaa,bbb,ccc"のストリームと、"ddd,eee,fff"のストリームに分かれてしまいます。
flatMapの場合は、これを"aaa,bbb,ccc,ddd,eee,fff"の一つのストリームとして返します。
ストリームをフラットにするので、flatMapという名前になっています。

    List<String> texts = Arrays.asList("aaa bbb ccc", "ddd eee fff");
    texts.stream()
            .flatMap(s -> Arrays.stream(s.split(" ")))
            .map(String::toUpperCase)
            .forEach(System.out::println);

結果

    AAA
    BBB
    CCC
    DDD
    EEE
    FFF

テストコード

@Test
public void flatMap() {
    List<String> texts = Arrays.asList("aaa bbb ccc", "ddd eee fff");
    texts.stream()
            .flatMap(s -> Arrays.stream(s.split(" ")))
            .map(String::toUpperCase)
            .forEach(System.out::println);

    List<String> list = texts.stream()
            .flatMap(s -> Arrays.stream(s.split(" ")))
            .map(String::toUpperCase)
            .collect(Collectors.toList());
    assertThat(list).containsOnly("AAA", "BBB", "CCC", "DDD", "EEE", "FFF");
}

flatMapToInt

flatMapToIntはflatMapと同様ですが、IntStreamを返します。

同様にLongStreamを返すflatMapToLong、DoubleStreamを返すflatMapToDoubleもあります。

各文字列をスペースで分割し、文字数を返すflatToInt。

    List<String> texts = Arrays.asList("a bb ccc", "dddd eeeee ffffff");
    texts.stream()
            .flatMapToInt(s -> {
                String[] str = s.split(" ");
                return Arrays.stream(str).mapToInt(String::length);
            })
            .boxed()
            .forEach(System.out::println);

結果

    1
    2
    3
    4
    5
    6

テストコード

@Test
public void flatMapToInt() {
    List<String> texts = Arrays.asList("a bb ccc", "dddd eeeee ffffff");
    texts.stream()
            .flatMapToInt(s -> {
                String[] str = s.split(" ");
                return Arrays.stream(str).mapToInt(String::length);
            })
            .boxed()
            .forEach(System.out::println);

    List<Integer> list = texts.stream()
            .flatMapToInt(s -> {
                String[] str = s.split(" ");
                return Arrays.stream(str).mapToInt(String::length);
            })
            .boxed()
            .collect(Collectors.toList());
    assertThat(list).containsOnly(1, 2, 3, 4, 5, 6);
}

distinct

distinctはストリームの各要素を一意にします。

intをdistinctで一意にする。

    // int
    IntStream.of(0, 1, 1, 2, 2, 3, 2, 1)
            .distinct()
            .forEach(System.out::println);

結果

    0
    1
    2
    3

Stringをdistinctで一意にする。

    // String
    Stream.of("a", "b", "c", "b", "c")
            .distinct()
            .forEach(System.out::println);

結果

    a
    b
    c

テストコード

@Test
public void distinct() {
    // int
    IntStream.of(0, 1, 1, 2, 2, 3, 2, 1)
            .distinct()
            .forEach(System.out::println);

    List<Integer> intList = IntStream.of(0, 1, 1, 2, 2, 3, 2, 1)
            .distinct()
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).containsOnly(0, 1, 2, 3);

    // String
    Stream.of("a", "b", "c", "b", "c")
            .distinct()
            .forEach(System.out::println);

    List<String> strList = Stream.of("a", "b", "c", "b", "c")
            .distinct()
            .collect(Collectors.toList());
    assertThat(strList).containsOnly("a", "b", "c");
}

sorted

sortedはストリームの要素をソートしたストリームを返します。

引数なしのsortedでは自然順序でソートされたストリームを返します。
引数ありのsortedでは引数にComparatorを取り、Comparatorにしたがってソートされたストリームを返します。

文字列の昇順ソート。

    // string sort asc
    Stream.of("abc", "abb", "aab", "adb")
            .sorted()
            .forEach(System.out::println);
    Stream.of("abc", "abb", "aab", "adb")
            .sorted(Comparator.naturalOrder())
            .forEach(System.out::println);

結果

    aab
    abb
    abc
    adb

降順の場合、引数にComparator.reverseOrder()を指定します。
文字列の降順ソート。

    // string sort desc
    Stream.of("abc", "abb", "aab", "adb")
            .sorted(Comparator.reverseOrder())
            .forEach(System.out::println);

結果

    adb
    abc
    abb
    aab

数字の昇順ソート。

    // int sort asc
    IntStream.of(2, 3, 1, 4, 6)
            .sorted()
            .forEach(System.out::println);

結果

    1
    2
    3
    4
    6

数字の降順ソート。

    // int sort desc
    IntStream.of(2, 3, 1, 4, 6)
            .boxed()
            .sorted(Comparator.reverseOrder())
            .forEach(System.out::println);

結果

    6
    4
    3
    2
    1

テストコード

@Test
public void sorted() {
    // string sort asc
    Stream.of("abc", "abb", "aab", "adb")
            .sorted()
            .forEach(System.out::println);
    Stream.of("abc", "abb", "aab", "adb")
            .sorted(Comparator.naturalOrder())
            .forEach(System.out::println);

    List<String> strList = Stream.of("abc", "abb", "aab", "adb")
            .sorted()
            .collect(Collectors.toList());
    assertThat(strList).containsSequence("aab", "abb", "abc", "adb");

    // string sort desc
    Stream.of("abc", "abb", "aab", "adb")
            .sorted(Comparator.reverseOrder())
            .forEach(System.out::println);

    List<String> reverseStrList = Stream.of("abc", "abb", "aab", "adb")
            .sorted(Comparator.reverseOrder())
            .collect(Collectors.toList());
    assertThat(reverseStrList).containsSequence("adb", "abc", "abb", "aab");

    // int sort asc
    IntStream.of(2, 3, 1, 4, 6)
            .sorted()
            .forEach(System.out::println);

    List<Integer> intList = IntStream.of(2, 3, 1, 4, 6)
            .boxed()
            .sorted()
            .collect(Collectors.toList());
    assertThat(intList).containsSequence(1, 2, 3, 4, 6);

    // int sort desc
    IntStream.of(2, 3, 1, 4, 6)
            .boxed()
            .sorted(Comparator.reverseOrder())
            .forEach(System.out::println);

    List<Integer> reverseIntList = IntStream.of(2, 3, 1, 4, 6)
            .boxed()
            .sorted(Comparator.reverseOrder())
            .collect(Collectors.toList());
    assertThat(reverseIntList).containsSequence(6, 4, 3, 2, 1);
}

unordered

ストリームの順序付けについては、sequentialなストリームとparallelストリームで
パフォーマンスへの影響が異なるようです。

順序付けされていない場合、ストリームの処理は順番は保障されないので、
同じ処理を繰り返すと、異なる順番の結果となる可能性があります。
これは、sequentialなストリームでもparallelストリームでも同じです。

順序付けされている場合、parallelストリームの場合は、処理効率が悪くなることがあるようです。
検出順序を気にしない処理の場合、unordered()で順序付けを解除することで、
パフォーマンスが向上することがあるようです。
sequentialなストリームの場合、順序付けされていてもパフォーマンスには影響しません。

https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/package-summary.html#Ordering

    IntStream.rangeClosed(1, 10)
            .map(i -> i + 1)
            .parallel()
            .unordered()
            .forEach(System.out::println);

結果

    8
    7
    10
    11
    9
    4
    6
    5
    3
    2

テストコード

@Test
public void unordered() {
    IntStream.rangeClosed(1, 10)
            .map(i -> i + 1)
            .parallel()
            .unordered()
            .forEach(System.out::println);

    List<Integer> intList = IntStream.rangeClosed(1, 10)
            .map(i -> i + 1)
            .parallel()
            .unordered()
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).contains(2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
}

limit

limitはストリームの要素を引数で指定した長さのストリームにして返します。
iterate()やgenerate()は何も指定しないと無限に要素を生成するため、
limitで生成する要素数を制限できます。

iterateでlimitを指定。

    // iterate
    IntStream.iterate(0, i -> i + 100)
            .limit(5)
            .forEach(System.out::println);

結果

    0
    100
    200
    300
    400

generateでlimitを指定。

    // generate
    Stream.generate(() -> "abc")
            .limit(5)
            .forEach(System.out::println);

結果

    abc
    abc
    abc
    abc
    abc

テストコード

@Test
public void limit() {
    // iterate
    IntStream.iterate(0, i -> i + 100)
            .limit(5)
            .forEach(System.out::println);

    List<Integer> intList = IntStream.iterate(0, i -> i + 100)
            .boxed()
            .limit(5)
            .collect(Collectors.toList());
    assertThat(intList).containsOnly(0, 100, 200, 300, 400);

    // generate
    Stream.generate(() -> "abc")
            .limit(5)
            .forEach(System.out::println);

    List<String> strList = Stream.generate(() -> "abc")
            .limit(5)
            .collect(Collectors.toList());
    assertThat(strList).containsOnly("abc", "abc", "abc", "abc", "abc");
}

skip

skipはストリームの最初から指定した数までの要素を切り捨てたストリームを返します。

0~100の要素から、最初から92個の要素をスキップ。

    // int
    IntStream.rangeClosed(0, 100)
            .skip(92)
            .forEach(System.out::println);

結果

    92
    93
    94
    95
    96
    97
    98
    99
    100

文字の要素から、最初から4つの要素をスキップ。

    // String
    Stream.of("a", "b", "c", "d", "e", "f", "g", "h")
            .skip(4)
            .forEach(System.out::println);

結果

    e
    f
    g
    h

テストコード

@Test
public void skip() {
    // int
    IntStream.rangeClosed(0, 100)
            .skip(92)
            .forEach(System.out::println);

    List<Integer> intList = IntStream.rangeClosed(0, 100)
            .skip(92)
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).containsSequence(92, 93, 94, 95, 96, 97, 98, 99, 100);

    // String
    Stream.of("a", "b", "c", "d", "e", "f", "g", "h")
            .skip(4)
            .forEach(System.out::println);

    List<String> strList = Stream.of("a", "b", "c", "d", "e", "f", "g", "h")
            .skip(4)
            .collect(Collectors.toList());
    assertThat(strList).containsSequence("e", "f", "g", "h");
}

peek

peekはストリームの要素を一切変更せずに、間に処理をはさみます。
ストリームを変更しないので、Consumerインターフェースを取り、戻り値がない関数を記述します。

ストリームの処理の途中経過などを見るために、System.out.printlnなどを入れて
デバッグに使うのが主な用途だと思います。

    Stream.of("a", "b", "c", "b", "c")
            .map(String::toUpperCase)
            .peek(s -> System.out.println("upper : " + s))
            .map(s -> s + s)
            .peek(System.out::println)
            .map(String::length)
            .forEach(System.out::println);

結果

    upper : A
    AA
    2
    upper : B
    BB
    2
    upper : C
    CC
    2
    upper : B
    BB
    2
    upper : C
    CC
    2

テストコード

@Test
public void peek() {
    Stream.of("a", "b", "c", "b", "c")
            .map(String::toUpperCase)
            .peek(s -> System.out.println("upper : " + s))
            .map(s -> s + s)
            .peek(System.out::println)
            .map(String::length)
            .forEach(System.out::println);

    List<Integer> list = Stream.of("a", "b", "c", "b", "c")
            .map(String::toUpperCase)
            .peek(s -> System.out.println("upper : " + s))
            .map(s -> s + s)
            .peek(System.out::println)
            .map(String::length)
            .collect(Collectors.toList());
    assertThat(list).containsOnly(2, 2, 2, 2, 2);
}

boxed

boxedはストリームの各要素をボクシングします。
IntStream、LongStream、DoubleStreamでそれぞれ定義されており、下記のボクシングを行います。

・IntStream: int ⇒ Integer
・LongStream: long ⇒ Long
・DoubleStream: double ⇒ Double

intをIntegerにボクシング。

    Stream<Integer> stream = IntStream.rangeClosed(0, 10)
            .boxed();
    stream.forEach(System.out::println);

結果

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

テストコード

@Test
public void boxed() {
    Stream<Integer> stream = IntStream.rangeClosed(0, 10)
            .boxed();
    stream.forEach(System.out::println);

    List<Integer> list = IntStream.rangeClosed(0, 10)
            .boxed()
            .collect(Collectors.toList());
    assertThat(list).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
}

asLongStream

asLongStreamはストリームの要素をlongに変換します。
同様にストリームの要素をdoubleに変換するasDoubleStreamもあります。

intからlongのストリームへ変換。

    IntStream.rangeClosed(1, 10)
            .asLongStream()
            .forEach(System.out::println);

結果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

テストコード

@Test
public void asLongStream() {
    IntStream.rangeClosed(1, 10)
            .asLongStream()
            .forEach(System.out::println);

    List<Long> list = IntStream.rangeClosed(1, 10)
            .asLongStream()
            .boxed()
            .collect(Collectors.toList());
    assertThat(list).containsOnly(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L);
}

テストコード全体

今回のテストコードの全体です。

StreamApiIntermediateOperationTest.java

package javase8;

import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;

public class StreamApiIntermediateOperationTest {
    @Test
    public void filter() {
        // int
        IntStream.rangeClosed(0, 10)
                .filter(i -> i > 5)
                .forEach(System.out::println);

        List<Integer> intList = IntStream.rangeClosed(0, 10)
                .filter(i -> i > 5)
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).containsOnly(6, 7, 8, 9, 10);

        // String
        String[] texts = {"aaa", "bbb", "ccc", "abc"};
        Arrays.stream(texts)
                .filter(text -> text.endsWith("c"))
                .forEach(System.out::println);

        List<String> strList = Arrays.stream(texts)
                .filter(text -> text.endsWith("c"))
                .collect(Collectors.toList());
        assertThat(strList).containsOnly("ccc", "abc");
    }

    @Test
    public void map() {
        // int -> int
        IntStream.rangeClosed(1, 10)
                .map(i -> i + 10)
                .forEach(System.out::println);

        List<Integer> intList = IntStream.rangeClosed(1, 10)
                .map(i -> i + 10)
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).containsOnly(11, 12, 13, 14, 15, 16, 17, 18, 19, 20);

        // String -> String
        String[] texts = {"aaa", "bbb", "ccc"};
        Arrays.stream(texts)
                .map(text -> "|" + text + "|")
                .forEach(System.out::println);

        List<String> strList = Arrays.stream(texts)
                .map(text -> "|" + text + "|")
                .collect(Collectors.toList());
        assertThat(strList).containsOnly("|aaa|", "|bbb|", "|ccc|");
    }

    @Test
    public void mapToInt() {
        // Stringからintへ変換
        String[] texts2 = {"aaa", "bbbb", "ccccc"};
        Arrays.stream(texts2)
                .mapToInt(String::length)
                .forEach(System.out::println);

        List<Integer> stringToInt = Arrays.stream(texts2)
                .mapToInt(String::length)
                .boxed()
                .collect(Collectors.toList());
        assertThat(stringToInt).containsOnly(3, 4, 5);
    }

    @Test
    public void mapToObj() {
        // intからStringへ変換
        IntStream.rangeClosed(1, 5)
                .mapToObj(i -> i + "yen")
                .forEach(System.out::println);

        List<String> intToString = IntStream.rangeClosed(1, 5)
                .mapToObj(i -> i + "yen")
                .collect(Collectors.toList());
        assertThat(intToString).containsOnly("1yen", "2yen", "3yen", "4yen", "5yen");
    }

    @Test
    public void flatMap() {
        List<String> texts = Arrays.asList("aaa bbb ccc", "ddd eee fff");
        texts.stream()
                .flatMap(s -> Arrays.stream(s.split(" ")))
                .map(String::toUpperCase)
                .forEach(System.out::println);

        List<String> list = texts.stream()
                .flatMap(s -> Arrays.stream(s.split(" ")))
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        assertThat(list).containsOnly("AAA", "BBB", "CCC", "DDD", "EEE", "FFF");
    }

    @Test
    public void flatMapToInt() {
        List<String> texts = Arrays.asList("a bb ccc", "dddd eeeee ffffff");
        texts.stream()
                .flatMapToInt(s -> {
                    String[] str = s.split(" ");
                    return Arrays.stream(str).mapToInt(String::length);
                })
                .boxed()
                .forEach(System.out::println);

        List<Integer> list = texts.stream()
                .flatMapToInt(s -> {
                    String[] str = s.split(" ");
                    return Arrays.stream(str).mapToInt(String::length);
                })
                .boxed()
                .collect(Collectors.toList());
        assertThat(list).containsOnly(1, 2, 3, 4, 5, 6);
    }

    @Test
    public void distinct() {
        // int
        IntStream.of(0, 1, 1, 2, 2, 3, 2, 1)
                .distinct()
                .forEach(System.out::println);

        List<Integer> intList = IntStream.of(0, 1, 1, 2, 2, 3, 2, 1)
                .distinct()
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).containsOnly(0, 1, 2, 3);

        // String
        Stream.of("a", "b", "c", "b", "c")
                .distinct()
                .forEach(System.out::println);

        List<String> strList = Stream.of("a", "b", "c", "b", "c")
                .distinct()
                .collect(Collectors.toList());
        assertThat(strList).containsOnly("a", "b", "c");
    }

    @Test
    public void sorted() {
        // string sort asc
        Stream.of("abc", "abb", "aab", "adb")
                .sorted()
                .forEach(System.out::println);
        Stream.of("abc", "abb", "aab", "adb")
                .sorted(Comparator.naturalOrder())
                .forEach(System.out::println);

        List<String> strList = Stream.of("abc", "abb", "aab", "adb")
                .sorted()
                .collect(Collectors.toList());
        assertThat(strList).containsSequence("aab", "abb", "abc", "adb");

        // string sort desc
        Stream.of("abc", "abb", "aab", "adb")
                .sorted(Comparator.reverseOrder())
                .forEach(System.out::println);

        List<String> reverseStrList = Stream.of("abc", "abb", "aab", "adb")
                .sorted(Comparator.reverseOrder())
                .collect(Collectors.toList());
        assertThat(reverseStrList).containsSequence("adb", "abc", "abb", "aab");

        // int sort asc
        IntStream.of(2, 3, 1, 4, 6)
                .sorted()
                .forEach(System.out::println);

        List<Integer> intList = IntStream.of(2, 3, 1, 4, 6)
                .boxed()
                .sorted()
                .collect(Collectors.toList());
        assertThat(intList).containsSequence(1, 2, 3, 4, 6);

        // int sort desc
        IntStream.of(2, 3, 1, 4, 6)
                .boxed()
                .sorted(Comparator.reverseOrder())
                .forEach(System.out::println);

        List<Integer> reverseIntList = IntStream.of(2, 3, 1, 4, 6)
                .boxed()
                .sorted(Comparator.reverseOrder())
                .collect(Collectors.toList());
        assertThat(reverseIntList).containsSequence(6, 4, 3, 2, 1);
    }

    @Test
    public void unordered() {
        IntStream.rangeClosed(1, 10)
                .map(i -> i + 1)
                .parallel()
                .unordered()
                .forEach(System.out::println);

        List<Integer> intList = IntStream.rangeClosed(1, 10)
                .map(i -> i + 1)
                .parallel()
                .unordered()
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).contains(2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
    }

    @Test
    public void limit() {
        // iterate
        IntStream.iterate(0, i -> i + 100)
                .limit(5)
                .forEach(System.out::println);

        List<Integer> intList = IntStream.iterate(0, i -> i + 100)
                .boxed()
                .limit(5)
                .collect(Collectors.toList());
        assertThat(intList).containsOnly(0, 100, 200, 300, 400);

        // generate
        Stream.generate(() -> "abc")
                .limit(5)
                .forEach(System.out::println);

        List<String> strList = Stream.generate(() -> "abc")
                .limit(5)
                .collect(Collectors.toList());
        assertThat(strList).containsOnly("abc", "abc", "abc", "abc", "abc");
    }

    @Test
    public void skip() {
        // int
        IntStream.rangeClosed(0, 100)
                .skip(92)
                .forEach(System.out::println);

        List<Integer> intList = IntStream.rangeClosed(0, 100)
                .skip(92)
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).containsSequence(92, 93, 94, 95, 96, 97, 98, 99, 100);

        // String
        Stream.of("a", "b", "c", "d", "e", "f", "g", "h")
                .skip(4)
                .forEach(System.out::println);

        List<String> strList = Stream.of("a", "b", "c", "d", "e", "f", "g", "h")
                .skip(4)
                .collect(Collectors.toList());
        assertThat(strList).containsSequence("e", "f", "g", "h");
    }

    @Test
    public void peek() {
        Stream.of("a", "b", "c", "b", "c")
                .map(String::toUpperCase)
                .peek(s -> System.out.println("upper : " + s))
                .map(s -> s + s)
                .peek(System.out::println)
                .map(String::length)
                .forEach(System.out::println);

        List<Integer> list = Stream.of("a", "b", "c", "b", "c")
                .map(String::toUpperCase)
                .peek(s -> System.out.println("upper : " + s))
                .map(s -> s + s)
                .peek(System.out::println)
                .map(String::length)
                .collect(Collectors.toList());
        assertThat(list).containsOnly(2, 2, 2, 2, 2);
    }

    @Test
    public void boxed() {
        Stream<Integer> stream = IntStream.rangeClosed(0, 10)
                .boxed();
        stream.forEach(System.out::println);

        List<Integer> list = IntStream.rangeClosed(0, 10)
                .boxed()
                .collect(Collectors.toList());
        assertThat(list).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    }

    @Test
    public void asLongStream() {
        IntStream.rangeClosed(1, 10)
                .asLongStream()
                .forEach(System.out::println);

        List<Long> list = IntStream.rangeClosed(1, 10)
                .asLongStream()
                .boxed()
                .collect(Collectors.toList());
        assertThat(list).containsOnly(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L);
    }
}

ソースは一応あげときました。

github.com

終わり。