๐Ÿ“– Stream ๋ถ€์ˆ˜๊ธฐ


์ฝ”๋“œ๋ฅผ ์งœ๋‹ค๋ณด๋ฉด ๊ฐ€๋…์„ฑ๊ณผ ๊ฐ„๊ฒฐํ•จ์„ ์œ„ํ•ด stream์„ ์ž์ฃผ ์“ฐ๊ฒŒ ๋œ๋‹ค.
ํ”„๋ฆฌ์ฝ”์Šค ๋•Œ Stream์— ๋Œ€ํ•ด ์ •๋ฆฌํ–ˆ์—ˆ์œผ๋‚˜,
๋‚ด๊ฐ€ ์“ด ๊ธ€์„ ๋ฆฌํŒฉํ† ๋ง(ใ…Ž) ํ•ด๋ณด๋ฉด์„œ ๋‹ค์‹œ ๊ฐœ๋…์„ ์ตํ˜€์•ผ ๊ฒ ๋‹ค.

์ŠคํŠธ๋ฆผ?

๋ฐฐ์—ด ๋˜๋Š” ์ปฌ๋ ‰์…˜ ์ธ์Šคํ„ด์Šค์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด์„œ ํŒŒ์ดํ”„์— ํ˜๋ ค๋ณด๋‚ธ๋‹ค.

  • ์ค‘๊ฐ„ ์—ฐ์‚ฐ : ๋งˆ์ง€๋ง‰์ด ์•„๋‹Œ ์œ„์น˜์—์„œ ์ง„ํ–‰์ด ๋˜์–ด์•ผ ํ•˜๋Š” ์—ฐ์‚ฐ
  • ์ตœ์ข… ์—ฐ์‚ฐ : ๋งˆ์ง€๋ง‰์— ์ง„ํ–‰์ด ๋˜์–ด์•ผ ํ•˜๋Š” ์—ฐ์‚ฐ ์ŠคํŠธ๋ฆผ์€ ์ค‘๊ฐ„ ์—ฐ์‚ฐ๊ณผ ์ตœ์ข… ์—ฐ์‚ฐ์„ ์ง„ํ–‰ํ•˜๊ธฐ ์ข‹์€ ๊ตฌ์กฐ๋กœ ๋ฐฐ์น˜๋œ ๋ณต์‚ฌ๋ณธ์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ŠคํŠธ๋ฆผ์˜ ํŠน์„ฑ

๊ฐ€๋…์„ฑ๊ณผ ๊ฐ„๊ฒฐํ•จ

์ปฌ๋ ‰์…˜์ด๋‚˜ ๋ฐฐ์—ด์— ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด for๋ฌธ๊ณผ Iterator๋ฅผ ์ด์šฉํ•ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ณ  ์žฌ์‚ฌ์šฉ์„ฑ๋„ ๋–จ์–ด์ง„๋‹ค.

๋ฐ์ดํ„ฐ ์†Œ์Šค ์ถ”์ƒํ™”

์–ด๋–ค ๋ฉ”์†Œ๋“œ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ ์†Œ์Šค๋งˆ๋‹ค ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ค„์•ผ ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์ŠคํŠธ๋ฆผ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์†Œ์Šค๊ฐ€ ๋ฌด์—‡์ด๋˜ ๊ฐ„์— ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.
์ด๋Š” ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๊ฐ€์ ธ์˜จ๋‹ค.

Stream<String> listStream = strList.stream();
Stream<String> arrayStream = Arrays.stream(strArr);

listStream.sorted().forEach(System.out::println);
arrayStream.sorted().forEach(System.out::println);

๋‘ ์ŠคํŠธ๋ฆผ์˜ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” ์„œ๋กœ ๋‹ค๋ฅด์ง€๋งŒ, ์ •๋ ฌํ•˜๊ณ  ์ถœ๋ ฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ™๋‹ค.

๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋กœ ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ธฐ๋งŒ ํ•  ๋ฟ, ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.
ํ•„์š”์‹œ์—๋งŒ ์ •๋ ฌ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ปฌ๋ ‰์…˜์ด๋‚˜ ๋ฐฐ์—ด์— ๋‹ด์•„์„œ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

List<String> sortedList = listStream.sorted().collect(Collections.toList());

์ŠคํŠธ๋ฆผ์€ ์ผํšŒ์šฉ์ด๋‹ค.

Iterator์ฒ˜๋Ÿผ ์ผํšŒ์šฉ์ด๋‹ค. ํ•œ๋ฒˆ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ซํ˜€์„œ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
ํ•„์š”ํ•˜๋‹ค๋ฉด ์ŠคํŠธ๋ฆผ์„ ๋‹ค์‹œ ์ƒ์„ฑํ•ด์•ผํ•œ๋‹ค.

listStream.sorted().forEach(System.out::print);
int numOfElement = listStream.count(); //์—๋Ÿฌ- ์ŠคํŠธ๋ฆผ์ด ์ด๋ฏธ ๋‹ซํ˜”๋‹ค.

๋‚ด๋ถ€ ๋ฐ˜๋ณต

์ŠคํŠธ๋ฆผ์ด ๊ฐ„๊ฒฐํ•œ ์ด์œ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ˜๋ณต๋ฌธ์„ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์— ์ˆจ๊ธฐ๋Š” โ€˜๋‚ด๋ถ€ ๋ฐ˜๋ณตโ€™ ๋•๋ถ„์ด๋‹ค.
forEach()๋Š” ์ŠคํŠธ๋ฆผ์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ ์ค‘์˜ ํ•˜๋‚˜๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€์ž…๋œ ๋žŒ๋‹ค์‹์„ ๋ฐ์ดํ„ฐ ์†Œ์Šค์˜ ๋ชจ๋“  ์š”์†Œ์— ์ ์šฉํ•œ๋‹ค.

stream.forEach(System.out::println);

์ŠคํŠธ๋ฆผ ์ƒ์„ฑํ•˜๊ธฐ

์ŠคํŠธ๋ฆผ์˜ ์ƒ์„ฑ

๋ฉ”์†Œ๋“œ

์ŠคํŠธ๋ฆผ ์ƒ์„ฑ๊ณผ ๊ด€๋ จํ•ด Stream<T> ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜๋˜์–ด ์žˆ๋Š” static ๋ฉ”์†Œ๋“œ๋Š” ๋‘ ๊ฐœ๊ฐ€ ์žˆ๋‹ค.

static <T> Stream<T>(T t)
static <T> Stream<T> of(T...values)

์ด ๋ฉ”์†Œ๋“œ์— ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ž๋กœ ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

Example

class StreamOfStream {
    public static void main(String[] args) {
        // ex 1
        Stream.of(11, 22, 33, 44)
            .forEach(n -> System.out.print(n + "\t"));
        System.out.println();

        // ex 2
        Stream.of("So Simple")
            .forEach(s -> System.out.print(s + "\t"));
        System.out.println();

        // ex 3 ์„ธ ๊ฐœ์˜ ๋ฌธ์ž์—ด๋กœ ์ด๋ค„์ง„ ์ŠคํŠธ๋ฆผ์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ
        // sl์ด ์ฐธ์กฐํ•˜๋Š” ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ ์กด์žฌํ•œ๋‹ค.
        List<String> sl = Arrays.asList("Toy", "Robot", "Box");
        Stream.of(sl)
            .forEach(w -> System.out.print(w + "\t"));
        System.out.println();       
    }
}

of ๋ฉ”์†Œ๋“œ์— ์ปฌ๋ ‰์…˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํ•ด๋‹น ์ธ์Šคํ„ด์Šค ํ•˜๋‚˜๋กœ ์ด๋ค„์ง„ ์ŠคํŠธ๋ฆผ์ด ์ƒ์„ฑ๋œ๋‹ค.
ํ•˜์ง€๋งŒ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•˜๋ฉด ํ•˜๋‚˜์˜ ๋ฐฐ์—ด๋กœ ์ด๋ค„์ง„ ์ŠคํŠธ๋ฆผ์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๊ณ ,
๋ฐฐ์—ด์— ์ €์žฅ๋œ ์š”์†Œ๋กœ ์ด๋ค„์ง„ ์ŠคํŠธ๋ฆผ์ด ์ƒ์„ฑ๋œ๋‹ค.

๋ฐฐ์—ด

๋ฐฐ์—ด์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๋Œ€ํ‘œ ๋ฉ”์†Œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

public satic <T> Stream<T> stream(T[] array) // Arrays ํด๋ž˜์Šค์— ์ •์˜๋˜์–ด ์žˆ๋‹ค
class StringStream {
    public static void main(String[] args) {
        String[] names = {"YOON", "LEE", "PARK"};
        
        // ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ
        Stream<String> stm = Arrays.stream(names);
        
        // ์ตœ์ข… ์—ฐ์‚ฐ ์ง„ํ–‰
        stm.forEach(s -> System.out.println(s));
    }
}

forEach๋Š” ์ตœ์ข… ์—ฐ์‚ฐ์ด๋ฉฐ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ํ˜•์€ Consumer<T> ์ด๋ฏ€๋กœ ๋žŒ๋‹ค์‹์„ ์ธ์ž๋กœ ์ „๋‹ฌํ•ด์•ผํ•˜๋ฉฐ,
๋‚ด๋ถ€์ ์œผ๋กœ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์”ฉ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๋ฉด์„œ accept ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

์ปฌ๋ ‰์…˜ ์ธ์Šคํ„ด์Šค

์ปฌ๋ ‰์…˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์†Œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

default Stream<E> stream()
class ListStream {
    public static void main(String[] args) {
        
        List<String> list = Arrays.asList("Toy", "Robot", "Box");
        
        list.stream()
          .forEach(s -> System.out.print(s + "\t"));

        System.out.println();
    }
}

ํŠน์ • ๋ฒ”์œ„์˜ ์ •์ˆ˜

IntStream๊ณผ LongStream์€ ์ง€์ •๋œ ๋ฒ”์œ„์˜ ์—ฐ์†๋œ ์ •์ˆ˜๋ฅผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” range()์™€ rangeClosed()๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

IntStream intStream = IntStream.range(1, 5); // 1,2,3,4,
IntStream intStream = IntStream = Intstream.rangeClosed(1, 5); // 1,2,3,4,5 

range๋Š” end๊ฐ€ ๋ฒ”์œ„์— ํฌํ•จ๋˜์ง€ ์•Š๊ณ  rangeClosed๋Š” ํฌํ•จ๋œ๋‹ค.

๋žŒ๋‹ค์‹ - iterate(), generate()

Stream ํด๋ž˜์Šค์˜ iterate()์™€ generate()๋Š” ๋žŒ๋‹ค์‹์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์„œ,
์ด ๋žŒ๋‹ค์‹์— ์˜ํ•ด ๊ณ„์‚ฐ๋˜๋Š” ๊ฐ’๋“ค์„ ์š”์†Œ๋กœ ํ•˜๋Š” ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•œ๋‹ค.

์ด๋•Œ ์ƒ์„ฑ๋˜๋Š” ์ŠคํŠธ๋ฆผ์€ ๋ฌดํ•œํ•˜๊ธฐ ๋•Œ๋ฌธ์— limit()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํŠน์ • ์‚ฌ์ด์ฆˆ๋กœ ์ œํ•œํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

iterate()

Stream<Integer> evenStream = Stream.iterate(0, n -> n+2).limit(5);
// 0, 2, 4 ...

์”จ๋“œ๋กœ ์ง€์ •๋œ ๊ฐ’๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ, ๋žŒ๋‹ค์‹์— ์˜ํ•ด ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์‹œ๋“œ ๊ฐ’์œผ๋กœ ํ•ด์„œ ๊ณ„์‚ฐ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

generate()

Stream<Integer> randomStream = Stream.generate(Math::random).limit(5);

iterate()์ฒ˜๋Ÿผ ๋žŒ๋‹ค์‹์— ์˜ํ•ด ๊ณ„์‚ฐ๋˜๋Š” ๊ฐ’์„ ์š”์†Œ๋กœ ํ•˜๋Š” ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, iterate()์™€ ๋‹ฌ๋ฆฌ ์ด์ „ ๊ฒฐ๊ณผ๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค์Œ ์š”์†Œ๋ฅผ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋นˆ ์ŠคํŠธ๋ฆผ

์š”์†Œ๊ฐ€ ํ•˜๋‚˜๋„ ์—†๋Š” ๋น„์–ด์žˆ๋Š” ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
์ŠคํŠธ๋ฆผ์— ์—ฐ์‚ฐ์„ ์ˆ˜ํ•ธํ•œ ๊ฒฐ๊ณผ๊ฐ€ ํ•˜๋‚˜๋„ ์—†์„ ๋•Œ, null๋ณด๋‹ค ๋นˆ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ฒŒ ๋‚ซ๋‹ค.

Stream emptyStream = Stream.empty(); // empty() ๋Š” ๋นˆ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
long count = emptyStream.count(); // count๊ฐ’์€ 0

์—ฌ๊ธฐ์„œ count()๋Š” ์š”์†Œ์˜ ๊ฐฏ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ŠคํŠธ๋ฆผ์˜ ์—ฐ์‚ฐ

์ง€์—ฐ ์ฒ˜๋ฆฌ

class MyFirstStream2 {
    public static void main(String[] args) {
        int[] ar = {1, 2, 3, 4, 5};

        int sum = Arrays.stream(ar) // ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑ
                        .filter(n -> n%2 == 1) // filter ํ†ต๊ณผ
                        .sum(); // sum์„ ํ†ต๊ณผ์‹œ์ผœ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜

        System.out.println(sum);
    }
}

์œ„ ์˜ˆ์ œ์—์„œ ์“ฐ์ธ ๋‘ ๋ฉ”์†Œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

public static IntStream stream(int[] array)
IntStream filter(IntPredicate predicate)

filter์™€ sum ๋ฉ”์†Œ๋“œ๋Š” IntStream์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ์ด๋‹ค.

์ŠคํŠธ๋ฆผ์˜ ์—ฐ์‚ฐ์€ โ€œ์ง€์—ฐ ์ฒ˜๋ฆฌโ€ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.
์ตœ์ข… ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰ ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

์œ„ ์˜ˆ์ œ์—์„œ๋Š” sum์ด ํ˜ธ์ถœ๋  ๋•Œ๊นŒ์ง€ filter์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋Š” ์ŠคํŠธ๋ฆผ์— ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š”๋‹ค.
์ตœ์ข… ์—ฐ์‚ฐ์ธ sum์ด ํ˜ธ์ถœ๋˜์–ด์•ผ๋งŒ filter์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๊ฐ€ ์ŠคํŠธ๋ฆผ์— ๋ฐ˜์˜๋œ๋‹ค.
์ด์ฒ˜๋Ÿผ ์ตœ์ข… ์—ฐ์‚ฐ์ด ์ƒ๋žต๋˜๋ฉด ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.

์ŠคํŠธ๋ฆผ์˜ ์ค‘๊ฐ„ ์—ฐ์‚ฐ

์—ฐ์‚ฐ ๊ฒฐ๊ณผ๊ฐ€ ์ŠคํŠธ๋ฆผ์ธ ์—ฐ์‚ฐ์œผ๋กœ, ์ŠคํŠธ๋ฆผ์— ์—ฐ์†ํ•ด์„œ ์ค‘๊ฐ„ ์—ฐ์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

filter (ํ•„ํ„ฐ๋ง)

์ŠคํŠธ๋ฆผ์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ค‘ ์ผ๋ถ€๋ฅผ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๊ฑธ๋Ÿฌ๋‚ด๋Š” ํ–‰์œ„๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

๋ฉ”์†Œ๋“œ

Stream<T> filter(Predicate<? super T> predicate) // Stream<T>์— ์กด์žฌ

๋งค๊ฐœ๋ณ€์ˆ˜ ํ˜•์ด Predicate์ด๋ฏ€๋กœ test ๋ฉ”์†Œ๋“œ์˜ ๊ตฌํ˜„์— ํ•ด๋‹นํ•˜๋Š” ๋žŒ๋‹ค์‹์„ ์ธ์ž๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.
๋‚ด๋ถ€์ ์œผ๋กœ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์”ฉ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๋ฉด์„œ test๋ฅผ ํ˜ธ์ถœํ•˜๊ณ ,
๊ทธ ๊ฒฐ๊ณผ๊ฐ€ true์ด๋ฉด ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ŠคํŠธ๋ฆผ์— ๋‚จ๊ธด๋‹ค.

class FilterStream {
    public static void main(String[] args) {
        int[] ar = {1, 2, 3, 4, 5};
        Arrays.stream(ar)
            .filter(n -> n%2 == 1) // ํ™€์ˆ˜๋งŒ ํ†ต๊ณผ
            .forEach(n -> System.out.print(n + "\t"));
        System.out.println();

        List<String> sl = Arrays.asList("Toy", "Robot", "Box");
        sl.stream()
            .filter(s -> s.length() == 3) // ๊ธธ์ด๊ฐ€ 3์ด๋ฉด ํ†ต๊ณผ
            .forEach(s -> System.out.print(s + "\t"));
        System.out.println();       
    }
}

map (๋งตํ•‘)

์ŠคํŠธ๋ฆผ ์š”์†Œ์—์„œ ์ €์žฅ๋œ ๊ฐ’ ์ค‘์—์„œ ์›ํ•˜๋Š” ํ•„๋“œ๋งŒ ๋ฝ‘์•„๋‚ด๊ฑฐ๋‚˜ ํŠน์ • ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•  ๋–„๊ฐ€ ์žˆ๋‹ค.
๋งตํ•‘์„ ์ง„ํ–‰ํ•˜๋ฉด ์ŠคํŠธ๋ฆผ์˜ ๋ฐ์ดํ„ฐ ํ˜•์ด ๋‹ฌ๋ผ์ง€๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.

๋ฉ”์†Œ๋“œ

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

๋งค๊ฐœ๋ณ€์ˆ˜ ํ˜•์ด Function์ด๋ฏ€๋กœ apply ๋ฉ”์†Œ๋“œ์˜ ๊ตฌํ˜„์— ํ•ด๋‹นํ•˜๋Š” ๋žŒ๋‹ค์‹์„ ์ธ์ž๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.
๋‚ด๋ถ€์ ์œผ๋กœ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์”ฉ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๋ฉด์„œ apply๋ฅผ ํ˜ธ์ถœํ•˜๊ณ ,
๊ทธ ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์„ ๋ชจ์•„ ์ƒˆ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•œ๋‹ค.

class MapToInt {
    public static void main(String[] args) {
        List<String> ls = Arrays.asList("Box", "Robot", "Simple");
        
        ls.stream()
          .map(s -> s.length())
          .forEach(n -> System.out.print(n + "\t"));
        
        System.out.println();
    }
}

map vs flatMap

map์˜ ๋ฉ”์†Œ๋“œ
<R> Stream<R> map(Function<T, R> mapper)

map์— ์ „๋‹ฌํ•  ๋žŒ๋‹ค์‹์—์„œ๋Š” ์ŠคํŠธ๋ฆผ์„ ๊ตฌ์„ฑํ•  ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋œ๋‹ค.

flatMap์˜ ๋ฉ”์†Œ๋“œ
<R> Stream<R> flatMap(Function<T, Stream<R>> mapper)

flatMap์— ์ „๋‹ฌํ•  ๋žŒ๋‹ค์‹์—์„œ๋Š” ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

filter & map

example

int sum = ls.stream()
	.filter(p -> p.getPrice() < 500)
	.mapToInt(t -> t.getPrice())
	.sum();

sorted

๋ฉ”์†Œ๋“œ

Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> compatator)

sorted()๋Š” ์ง€์ •๋œ Comparator๋กœ ์ŠคํŠธ๋ฆผ์„ ์ •๋ ฌํ•˜๋Š”๋ฐ, Comparator๋Œ€์‹  int ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋žŒ๋‹ค์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
Comparator๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ŠคํŠธ๋ฆผ ์š”์†Œ์˜ ๊ธฐ๋ณธ ์ •๋ ฌ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.
ํ•˜์ง€๋งŒ ์ŠคํŠธ๋ฆผ ์š”์†Œ๊ฐ€ Comparable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
์ •๋ ฌ์— ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์„œ๋“œ์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋งŽ์ง€๋งŒ ๊ธฐ๋ณธ์ ์ธ ๋ฉ”์„œ๋“œ๋Š” comparing()์ด๋‹ค.

comparing(Function<T, U> keyExtractor)
comparing(Function<T, U> keyExtractor, Comparator<U> keyComparator)

์ŠคํŠธ๋ฆผ ์š”์†Œ๊ฐ€ Comparable์„ ๊ตฌํ˜„ํ•œ ๊ฒฝ์šฐ, ๋งค๊ฐœ๋ณ€์ˆ˜ ํ•˜๋‚˜์งœ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ณ ,
๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ถ”๊ฐ€์ ์ธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ •๋ ฌ๊ธฐ์ค€(Comparator)์„ ๋”ฐ๋กœ ์ง€์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

์ •๋ ฌ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” thenComparing()์„ ์‚ฌ์šฉํ•œ๋‹ค.

Example

ํ•™์ƒ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜๋ณ„, ์„ฑ์ ์ˆœ, ์ด๋ฆ„ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๋Š” ์˜ˆ์‹œ์ด๋‹ค.

student.sorted(Comparator.comparing(Student::getBan)
	.thenComparing(Student::getTOtalScore)
        .thenComparing(Student::getName)
        .forEach(System.out.println);

peek

์ŠคํŠธ๋ฆผ์„ ์ด๋ฃจ๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๊ฐ๊ฐ์„ ๋Œ€์ƒ์œผ๋กœ ํŠน์ • ์—ฐ์‚ฐ์„ ์ง„ํ–‰ํ•˜๋Š” ํ–‰์œ„๋ฅผ โ€œ๋ฃจํ•‘โ€์ด๋ผ ํ•œ๋‹ค.
forEach๋Š” ๋ฃจํ•‘์œผ๋กœ ์ตœ์ข…์—ฐ์‚ฐ์ด์ง€๋งŒ, ์ค‘๊ฐ„์—ฐ์‚ฐ์—๋„ ๋ฃจํ•‘ ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๋‹ค.

๋ฉ”์†Œ๋“œ

// Stream<T>์˜ ๋ฉ”์†Œ๋“œ
Stream<T> peek(Consumer<? super T> action)

Example

class LazyOpStream {
    public static void main(String[] args) {
        // ์ตœ์ข… ์—ฐ์‚ฐ์ด ์ƒ๋žต๋œ ์ŠคํŠธ๋ฆผ์˜ ํŒŒ์ดํ”„ ๋ผ์ธ
        // ์•„๋ฌด ๊ฒƒ๋„ ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š”๋‹ค.
        IntStream.of(1, 3, 5)
            .peek(d -> System.out.print(d + "\t"));
        System.out.println();

  
        // ์ตœ์ข… ์—ฐ์‚ฐ์ด ์กด์žฌํ•˜๋Š” ํŒŒ์ดํ”„ ๋ผ์ธ
        IntStream.of(5, 3, 1)
            .peek(d -> System.out.print(d + "\t"))
            .sum();            
        System.out.println();
    }
}

์ŠคํŠธ๋ฆผ์˜ ์ตœ์ข… ์—ฐ์‚ฐ

์ตœ์ข… ์—ฐ์‚ฐ์€ ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์†Œ๋ชจํ•ด์„œ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค.
๊ทธ๋ž˜์„œ ์ตœ์ข… ์—ฐ์‚ฐ ํ›„์—๋Š” ์ŠคํŠธ์ž„๋‹ˆ ๋‹ซํ˜€ ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
์ตœ์ข… ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๋Š” ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ์˜ ํ•ฉ๊ณผ ๊ฐ™์€ ๋‹จ์ผ ๊ฐ’์ด๊ฑฐ๋‚˜,
์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด ๋˜๋Š” ์ปฌ๋ ‰์…˜์ผ ์ˆ˜ ์žˆ๋‹ค.

forEach

์ง€์ •๋œ ์ž‘์—…์„ ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฃผ์˜ํ•  ์ ์€ forEach()๋Š” ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์†Œ๋ชจํ•˜๋ฉด์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ๊ฐ™์€ ์ŠคํŠธ๋ฆผ์— forEach()๋ฅผ ๋‘ ๋ฒˆ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋‹ค.

๋ฉ”์†Œ๋“œ

// Stream<T>์˜ ๋ฉ”์†Œ๋“œ
void forEach(Consumer<? super T> action)

peek()๊ณผ ๋‹ฌ๋ฆฌ ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์†Œ๋ชจํ•˜๋Š” ์ตœ์ข… ์—ฐ์‚ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜ํ™˜ํ˜•์ด void์ด๋‹ค.

reduce

์ŠคํŠธ๋ฆผ ์š”์†Œ๋ฅผ ์ค„์—ฌ๋‚˜๊ฐ€๋ฉด์„œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
์ฒ˜์Œ ๋‘ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์—ฐ์‚ฐํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ง€๊ณ  ๊ทธ ๋‹ค์Œ ์š”์†Œ์™€ ์—ฐ์‚ฐํ•œ๋‹ค.
์ด ๊ณผ์ •์—์„œ ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ์†Œ๋ชจํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์†Œ๋ชจํ•˜๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๊ฐ€ ํ•˜๋‚˜๋„ ์—†๋Š” ๊ฒฝ์šฐ, ์ดˆ๊ธฐ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๋ฏ€๋กœ ๋ฐ˜ํ™˜ํƒ€์ž…์ด Optional<T>๊ฐ€ ์•„๋‹ˆ๋ผ T์ด๋‹ค.

๋ฉ”์†Œ๋“œ

T reduce(T identity, BinaryOperator<T> accumulator) // Stream<T>์— ์กด์žฌ

reduce๋Š” ์ „๋‹ฌํ•˜๋Š” ๋žŒ๋‹ค์‹์— ์˜ํ•ด ์—ฐ์‚ฐ์˜ ๋‚ด์šฉ์ด ๊ฒฐ์ •๋œ๋‹ค.

BinaryOperator<T>์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ

T apply(T t1, T t2)

reduce ํ˜ธ์ถœ ์‹œ ๋ฉ”์†Œ๋“œ apply์— ๋Œ€ํ•œ ๋žŒ๋‹ค์‹์„ ์ธ์ž๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.

class ReduceStream {
    public static void main(String[] args) {
        List<String> ls = Arrays.asList("Box", "Simple", "Complex", "Robot");
        
        BinaryOperator<String> lc = 
            (s1, s2) -> { 
               if(s1.length() > s2.length())
                   return s1;
               else 
                   return s2;                   
            };
        
        String str = ls.stream()
                      .reduce("", lc); // ์ŠคํŠธ๋ฆผ์ด ๋นˆ ๊ฒฝ์šฐ ๋นˆ ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜
      
        System.out.println(str); // Complex
    }
}

reduce ๋ฉ”์†Œ๋“œ๋Š” ์ŠคํŠธ๋ฆผ์ด ๋นˆ ๊ฒฝ์šฐ์— ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

allMatch, anyMatch, noneMatch

์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ์— ๋Œ€ํ•ด ์ง€์ •๋œ ์กฐ๊ฑด์— ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์ผ์น˜ํ•˜๋Š” ์ง€, ์ผ๋ถ€๊ฐ€ ์ผ์น˜ํ•˜๋Š”์ง€,
์•„๋‹ˆ๋ฉด ์–ด๋–ค ์š”์†Œ๋„ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์†Œ๋“œ

boolean allMatch(Predicate<? super Y> predicate)

boolean anyMatch(Predicate<? super Y> predicate)

boolean noneMatch(Predicate<? super Y> predicate)
  • allMatch : ์ŠคํŠธ๋ฆผ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋Š”๊ฐ€?
  • anyMatch : ์ŠคํŠธ๋ฆผ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐ๊ฑด์„ ํ•˜๋‚˜๋ผ๋„ ๋งŒ์กฑํ•˜๋Š”๊ฐ€?
  • noneMatch : ์ŠคํŠธ๋ฆผ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์กฐ๊ฑด์„ ํ•˜๋‚˜๋„ ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š”๊ฐ€?

    findAny, findFirst

    filter()์™€ ํ•จ๊ป˜ ์“ฐ์—ฌ์„œ ์กฐ๊ฑด์— ๋งž๋Š” ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
    ๋‘˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์€ Optionsnal<T>์ด๋ฉฐ, ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๊ฐ€ ์—†์„ ๋•Œ ๋นˆ Optional ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Example

Optional<Student> result = student.filer(s -> s.getTotalScore() <= 100).findFirst();

collect

ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ตํ•ด์„œ ๊ฐ€๊ณต๋˜๊ณ  ๊ฑธ๋Ÿฌ์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ข… ์—ฐ์‚ฐ ๊ณผ์ •์—์„œ ๋ณ„๋„๋กœ ์ €์žฅ์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๋ฉ”์†Œ๋“œ

// Stream<T>์˜ ๋ฉ”์†Œ๋“œ
<R> R collect(Supplier<R> supplier, 
				BiConsumer<R, ? super T> accumulator,
                BiConsumer<R, R> combiner)

Example

class CollectStringStream {
    public static void main(String[] args) {
        String[] words = {"Hello", "Box", "Robot", "Toy"};
        Stream<String> ss = Arrays.stream(words);
        
        List<String> ls = ss.filter(s -> s.length() < 5)
                          .collect(
                              () -> new ArrayList<>(),
                              (c, s) -> c.add(s),
                              (lst1, lst2) -> lst1.addAll(lst2));
    
        System.out.println(ls); // [Box, Toy]
    }
}

์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์ธ ๋žŒ๋‹ค์‹์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ €์žฅ์†Œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์ธ ๋žŒ๋‹ค์‹์—์„œ์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜(c)๋Š” collect์˜ ์ฒซ๋ฒˆ์งธ ์ธ์ž๋ฅผ ํ†ตํ•ด์„œ ์ƒ์„ฑ๋œ ์ปฌ๋ ‰์…˜ ์ธ์Šคํ„ด์Šค์ด๋ฉฐ,
๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜(s)๋Š” ์ŠคํŠธ๋ฆผ์„ ์ด๋ฃจ๋Š” ๋ฐ์ดํ„ฐ ์ด๋‹ค.
์„ธ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์ธ ๋žŒ๋‹ค์‹์€ ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ์ด ์•„๋‹Œ ์ˆœ์ฐจ ์ŠคํŠธ๋ฆผ์ผ ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

collect()

์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ์ตœ์ข… ์—ฐ์‚ฐ์œผ๋กœ reduce()์™€ ์œ ์‚ฌํ•˜๋‹ค.
collect()๊ฐ€ ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์ˆ˜์ง‘ํ•˜๋ ค๋ฉด, ์–ด๋–ป๊ฒŒ ์ˆ˜์ง‘ํ•  ๊ฒƒ์ธ๊ฐ€์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•์ด ์ •์˜๋˜์–ด
์žˆ์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ด ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•œ ๊ฒƒ์ด ์ปฌ๋ ‰ํ„ฐ์ด๋‹ค.

์ปฌ๋ ‰ํ„ฐ

์ปฌ๋ ‰ํ„ฐ๋Š” Collector ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ์œผ๋กœ, ์ง์ ‘ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๊ณ  ๋ฏธ๋ฆฌ ์ž‘์„ฑ๋œ ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
๋‹ค์–‘ํ•œ static ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

  • collect() : ์ŠคํŠธ๋ฆผ์˜ ์ตœ์ข…์—ฐ์‚ฐ, ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ํ•„์š”๋กœ ํ•œ๋‹ค.
  • Collector : ์ธํ„ฐํŽ˜์ด์Šค. ์ปฌ๋ ‰ํ„ฐ๋Š” ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.
  • Collectors : ํด๋ž˜์Šค. static ๋ฉ”์„œ๋“œ๋กœ ๋ฏธ๋ฆฌ ์ž‘์„ฑ๋œ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

Collector๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘ ๊ตฌํ˜„ํ•ด์„œ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

collect()

collect()๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์ด Collector์ธ๋ฐ, ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ Collector๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด์—ฌ์•ผ ํ•œ๋‹ค.
collect()๋Š” ์ด ๊ฐ์ฒด์— ๊ตฌํ˜„๋œ ๋ฐฉ๋ฒ•๋Œ€๋กœ ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์ˆ˜์ง‘ํ•œ๋‹ค.
sort()ํ•  ๋•Œ Comparator๊ฐ€ ํ•„์š”ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ colllect()ํ•  ๋•Œ๋Š” Collector๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Object collect(Collector collector) 

์ŠคํŠธ๋ฆผ์„ ์ปฌ๋ ‰์…˜๊ณผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜

  • toList(), toSet(), toMap(), toCollection(), toArray()

์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ปฌ๋ ‰์…˜์— ์ˆ˜์ง‘ํ•˜๋ ค๋ฉด, Collectors ํด๋ž˜์Šค์˜ toList()์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
ํŠน์ • ์ปฌ๋ ‰์…˜์„ ์ง€์ •ํ•˜๋ ค๋ฉด toCollection()์— ํ•ด๋‹นํ•˜๋Š” ์ปฌ๋ ‰์…˜์˜ ์ƒ์„ฑ์ž ์ฐธ์กฐ๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

ArrayList<String> list = names.stream().collect(Collectors.toCollection(toCollection(ArrayList::new));

Map์€ ํ‚ค์™€ ๊ฐ’์˜ ์Œ์œผ๋กœ ์ €์žฅํ•ด์•ผํ•˜๋‹ˆ ๊ฐ์ฒด์˜ ์–ด๋–ค ํ•„๋“œ๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ• ์ง€์™€ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ• ์ง€๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
์•„๋ž˜ ์˜ˆ์ œ๋Š” ์ŠคํŠธ๋ฆผ์—์„œ ์‚ฌ๋žŒ์˜ ์ฃผ๋ฏผ๋ฒˆํ˜ธ๋ฅผ ํ‚ค๋กœ ํ•˜๊ณ , ๊ฐ’์œผ๋กœ Person ๊ฐ์ฒด๋ฅผ ๊ทธ๋Œ€๋กœ ์ €์žฅํ•œ๋‹ค.

Map<String, Person> map  = personStream.collect(Collectors.toMap(p->p.getRegId(), p->p));

์ฐธ๊ณ  ์ž๋ฃŒ

  • ์ž๋ฐ”์˜ ์ •์„
  • ์œค์„ฑ์šฐ์˜ ์—ดํ˜ˆ ์ž๋ฐ” ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์ž์ฃผ ์‚ฌ์šฉํ•˜๋˜ ์ŠคํŠธ๋ฆผ์„ ์ •๋ฆฌํ•˜๋‹ˆ๊นŒ ๊ฐ ๋ฉ”์†Œ๋“œ์˜ ์‚ฌ์šฉ ๋ชฉ์ ์ด ๋ช…ํ™•ํ•ด์กŒ๋‹ค ๐Ÿ™ƒ
๋˜ Collector์™€ Collectors๋Š” ๋ญ๊ฐ€ ๋‹ค๋ฅธ์ง€ ๊ถ๊ธˆํ–ˆ๋Š”๋ฐ ์ •๋ฆฌ๋˜์—ˆ๋‹ค.