๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“– Java&Spring/๋ชจ๋˜์ž๋ฐ”์ธ์•ก์…˜

[๋ชจ๋˜์ž๋ฐ”์ธ์•ก์…˜] Stream ์ŠคํŠธ๋ฆผ

์ŠคํŠธ๋ฆผ (Stream)

์ปฌ๋ ‰์…˜(collections)๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปฌ๋ ‰์…˜์€ ๋ชจ๋“  ์ž๋ฐ” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ž‘์—…์— ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•˜๋‹ค.ํ•˜์ง€๋งŒ ์•„์ง ์™„๋ฒฝํ•œ ์ปฌ๋ ‰์…˜ ์—ฐ์‚ฐ์„ ์ง€์›ํ•˜๋ ค๋ฉด ๋ถ€์กฑํ•˜๋‹ค.

์ŠคํŠธ๋ฆผ์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€

์ŠคํŠธ๋ฆผ๋„ ์ž๋ฐ” 8 API์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ์ด๋‹ค.
๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์งˆ์˜๋กœ ํ‘œํ˜„ํ•˜์—ฌ ์„ ์–ธํ˜•์œผ๋กœ ์ปฌ๋ ‰์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

    @Test
    @DisplayName("์š”๋ฆฌ ํด๋ž˜์Šค ์ •๋ ฌํ•˜๊ธฐ")
    void sortExample() {
        List<Dish> menuList = new ArrayList<>();
        menuList.add(new Dish(100,"๋‹ญ๊ฐ€์Šด์‚ด"));
        menuList.add(new Dish(1500, "์น˜ํ‚จ"));
        menuList.add(new Dish(500, "์Šคํ”„"));

        List<Dish> lowCaloricDishes = new ArrayList<>();
        for (Dish lowCaloricDish : menuList) {
            if(lowCaloricDish.getCalories() < 1000) {
                lowCaloricDishes.add(lowCaloricDish);
            }
        }

        Collections.sort(lowCaloricDishes, Comparator.comparingInt(Dish::getCalories));

        List<String> lowCalDishesName = new ArrayList<>();
        for (Dish lowCaloricDish : lowCaloricDishes) {
            lowCalDishesName.add(lowCaloricDish.getName());
        }
    }

 

์œ„ ์˜ˆ์ œ์—์„œ๋Š” lowCaloricDishes ๋ผ๋Š” ๊ฐ€๋น„์ง€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ๋งŒ ํ•˜๋„๋ก ์‚ฌ์šฉํ•˜์˜€๋‹ค.

Dish ํด๋ž˜์Šค ๋ฆฌ์ŠคํŠธ์—์„œ 1000 ์นผ๋กœ๋ฆฌ ์ดํ•˜์˜ ์š”๋ฆฌ๋งŒ ๊ณจ๋ผ์„œ, ์นผ๋กœ๋ฆฌ๋กœ ์ •๋ ฌ์„ ํ•˜์—ฌ ์ด๋ฆ„์„ ์–ป๊ณ  ์‹ถ์„ ๋ฟ์ธ๋ฐ, ๊ฐ€๋น„์ง€ ๋ณ€์ˆ˜๋กœ ์ธํ•ด ๋น„ํšจ์œจ์ ์œผ๋กœ ๋ณด์ธ๋‹ค.

์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ”๊พธ๊ฒŒ ๋˜๋ฉด ์š”๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

    @Test
    @DisplayName("์š”๋ฆฌ ํด๋ž˜์Šค๋ฅผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ")
    void sortStreamExample() {
        List<String> lowCalDishesName = menuList.stream()
                .filter(dish -> dish.getCalories() < 1000)
                .sorted(Comparator.comparing(Dish::getCalories))
                .map(Dish::getName)
                .collect(Collectors.toList());
    }

 

ํ•œ ์ค„๋งŒ ๋ฐ”๊พธ๊ธฐ

 

@Test
    @DisplayName("์š”๋ฆฌ ํด๋ž˜์Šค๋ฅผ parallel ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ")
    void parallelStreamExample() {
        List<String> lowCalDishesName = menuList.parallelStream()
                .filter(dish -> dish.getCalories() < 1000)
                .sorted(Comparator.comparing(Dish::getCalories))
                .map(Dish::getName)
                .collect(Collectors.toList());
    }

 

stream()๋ฅผ parallelStream()๋กœ ๋ฐ”๊พธ๋ฉด ๋ฉ€ํ‹ฐ์ฝ”์–ด ์•„ํ‚คํ…์ณ์—์„œ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

??

๋ง์„ ํ’€์–ด์„œ ์„ค๋ช…ํ•˜์ž๋ฉด,

stream()์™€ parallelStream()๋Š” Java์˜ ์ŠคํŠธ๋ฆผ API์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ์ธ๋ฐ, ์ด๋“ค์€ ์ปฌ๋ ‰์…˜(์˜ˆ: ๋ฆฌ์ŠคํŠธ, ์„ธํŠธ, ๋งต ๋“ฑ)์— ๋Œ€ํ•ด ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

 

  1. stream() ๋ฉ”์†Œ๋“œ:
    • stream() ๋ฉ”์†Œ๋“œ๋Š” ์š”์†Œ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑ
    • ์ˆœ์ฐจ ์ŠคํŠธ๋ฆผ์€ ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ๊ฐ ์š”์†Œ๋Š” ์ด์ „ ์š”์†Œ์˜ ์ฒ˜๋ฆฌ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ
    List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
    
    // ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ
    myList.stream().forEach(System.out::println);
  2. parallelStream() ๋ฉ”์†Œ๋“œ:
    • parallelStream() ๋ฉ”์†Œ๋“œ๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๋™์‹œ์— ์š”์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑ
    • ๋ณ‘๋ ฌ ์ŠคํŠธ๋ฆผ์€ ๋ฉ€ํ‹ฐ์ฝ”์–ด ์•„ํ‚คํ…์ฒ˜์—์„œ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ
    List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
    
    // ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌ
    myList.parallelStream().forEach(System.out::println);

๋”ฐ๋ผ์„œ "stream()๋ฅผ parallelStream()์œผ๋กœ ๋ฐ”๊พธ๋ฉด ๋ฉ€ํ‹ฐ์ฝ”์–ด ์•„ํ‚คํ…์ฒ˜์—์„œ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค"๋Š” ๋ง์€, ์ˆœ์ฐจ์ ์ธ ์ฒ˜๋ฆฌ์—์„œ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌ๋กœ ์ „ํ™˜ํ•˜๋ฉด ๋ฉ€ํ‹ฐ์ฝ”์–ด ์‹œ์Šคํ…œ์—์„œ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
(๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๊ฐ€ ๋ฌด์กฐ๊ฑด ์„ฑ๋Šฅ์ด ์ข‹์€ ๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹˜)

 

parallelStream() ํ˜ธ์ถœํ•ด์„œ ์ข‹์€ ์ 

  1. ์„ ์–ธํ˜•์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค.
    • if ๋ฌธ์ฒ˜๋Ÿผ ์ œ์–ด ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  '1000 ๋ณด๋‹ค ๋‚ฎ์€ ์นผ๋กœ๋ฆฌ์˜ ์š”๋ฆฌ๋งŒ ์„ ํƒ' ์ด๋ผ๋Š” ๋™์ž‘๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์—ฌ๋Ÿฌ ๋นŒ๋”ฉ ๋ธ”๋ก ์—ฐ์‚ฐ์„ ์—ฐ๊ฒฐํ•ด์„œ ๋ณต์žํ•œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

filter, sorted, map, collect ์—ฐ์‚ฐ์€ ๊ณ ์ˆ˜์ค€ ๋นŒ๋”ฉ ๋ธ”๋ก(high-level building block)์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์–ด์„œ ํŠน์ • ์Šค๋ ˆ๋”ฉ ๋ชจ๋ธ์— ์ƒ๊ด€ ์—†์ด ํˆฌ๋ช…ํ•˜๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์— ๋” ํ™œ์šฉํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค.

๊ทธ๋ฆฌ๊ณ , ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ณผ์ •์ด ๋ณ‘๋ ฌํ™”๋œ๋‹ค๋Š”๊ฑด!! ์Šค๋ ˆ๋“œ์™€ ๋ฝ์„ ๋”ฐ๋กœ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค... ๋„ˆ๋ฌด ์ข‹์€๋ฐ?

์ŠคํŠธ๋ฆผ API ํŠน์ง•

  • ์„ ์–ธํ˜•: ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค
  • ์กฐ๋ฆฝํ•  ์ˆ˜ ์žˆ๋‹ค
  • ์œ ์—ฐํ•˜๋‹ค
  • ๋ณ‘๋ ฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜์—ฌ ์„ฑ๋Šฅ์ด ์ข‹์•„์ง„๋‹ค

์ŠคํŠธ๋ฆผ ์‹œ์ž‘ํ•˜๊ธฐ

์ž๋ฐ” 8 ์ปฌ๋ ‰์…˜์— ์ถ”๊ฐ€๋œ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” stream()์„ ์•Œ์•„๋ณด์ž

์ŠคํŠธ๋ฆผ ์ •์˜

๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์—ฐ์‚ฐ์„ ์ง€์›ํ•˜๋„๋ก ์†Œ์Šค์—์„œ ์ถ”์ถœ๋œ ์—ฐ์†๋œ ์š”์†Œ

  1. ์—ฐ์†๋œ ์š”์†Œ
    ํŠน์ • ์š”์†Œ ํ˜•์‹์œผ๋กœ ์ด๋ค„์ง„ ์—ฐ์†๋œ ๊ฐ’ ์ง‘ํ•ฉ์˜ ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ณต.
  • ์ปฌ๋ ‰์…˜: ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ์ œ๋กœ, ์‹œ๊ฐ„๊ณผ ๊ณต๊ฐ„์˜ ๋ณต์žก์„ฑ๊ณผ ๊ด€๋ จ๋œ ์—ฐ์‚ฐ ์‹œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์ŠคํŠธ๋ฆผ: ๊ณ„์‚ฐ์„ ์ฃผ์ œ๋กœ, ๊ณ„์‚ฐ์‹์— ์ฃผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. (filter, sorted, map ๋“ฑ)
  1. ์†Œ์Šค
    ์ปฌ๋ ‰์…˜, ๋ฐฐ์—ด, I/O ๋ฐ์ดํ„ฐ ์ œ๊ณต ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์†Œ๋น„ํ•œ๋‹ค.

์ •๋ ฌ๋œ ์†Œ์Šค๋กœ ์ŠคํŠธ๋ฆผ์„ ๋งŒ๋“ค๋ฉด ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ฆฌ์ŠคํŠธ๋กœ ์ŠคํŠธ๋ฆผ์„ ๋งŒ๋“ค๋ฉด ์š”์†Œ์˜ ์ˆœ์„œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์ˆœ์„œ์™€ ๊ฐ™๋‹ค.

  1. ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์—ฐ์‚ฐ
    ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋น„์Šทํ•œ ์—ฐ์‚ฐ์„ ์ง€์›ํ•œ๋‹ค.

์ˆœ์ฐจ์ /๋ณ‘๋ ฌ๋กœ ์ŠคํŠธ๋ฆผ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ŠคํŠธ๋ฆผ ์ฃผ์š” ํŠน์ง•

  1. Pipelining
    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์งˆ์˜๋ฅผ ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ, ์ŠคํŠธ๋ฆผ ์—ฐ์‚ฐ์„ ์—ฐ๊ฒฐํ•ด์„œ ์ปค๋‹ค๋ž€ ํŒŒ์ดํ”„ ํ˜•ํƒœ๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์ŠคํŠธ๋ฆผ ์ž์‹ ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

laziness, short-circuiting ๊ฐ™์€ ์ตœ์ ํ™”๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค ํ•จ.

  1. ๋‚ด๋ถ€ ๋ฐ˜๋ณต
  • ์ปฌ๋ ‰์…˜: ๋ฐ˜๋ณต์ž๋ฅผ ์ด์šฉํ•ด์„œ ๋ช…์‹œ์ ์ธ ๋ฐ˜๋ณต
  • ์ŠคํŠธ๋ฆผ ๋‚ด๋ถ€ ๋ฐ˜๋ณต์„ ์ง€์›

์ŠคํŠธ๋ฆผ ์˜ˆ์ œ

    List<Dish> menuList = new ArrayList<>();

    @BeforeEach
    void setUp() {
        menuList.add(new Dish(100, "๋‹ญ๊ฐ€์Šด์‚ด", false, Type.MEAT));
        menuList.add(new Dish(1500, "์น˜ํ‚จ", false, Type.MEAT));
        menuList.add(new Dish(500, "์Šคํ”„", false, Type.OTHER));
        menuList.add(new Dish(50, "์•ผ์ฑ„๋ณถ์Œ", true, Type.OTHER));
    }
//
    @Test
    @DisplayName("์š”๋ฆฌ ํด๋ž˜์Šค๋ฅผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ")
    void sortStreamExample() {
        List<String> lowCalDishesName = menuList.stream()// menuList์—์„œ ์ŠคํŠธ๋ฆผ์„ ์–ป์–ด์˜ด
                .filter(dish -> dish.getCalories() < 1000)// ํŒŒ์ดํ”„๋ผ์ธ ์—ฐ์‚ฐ์„ ๋งŒ๋“ฆ. 1000์นผ๋กœ๋ฆฌ๋ณด๋‹ค ์ ์€ ์š”๋ฆฌ๋ฅผ ํ•„ํ„ฐ๋ง ํ•œ๋‹ค.
                .sorted(Comparator.comparing(Dish::getCalories))
                .map(Dish::getName)// ์š”๋ฆฌ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜จ๋‹ค
                .limit(2)
                .collect(Collectors.toList()); // ์ŠคํŠธ๋ฆผ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค๋ฅธ ๋ฆฌ์ŠคํŠธ๋กœ ์ €์žฅํ•œ๋‹ค๋Š” ๋œป์ด์ž–์Šด~
    }
  1. ๋ฐ์ดํ„ฐ ์†Œ์Šค
    ์œ„์—์„œ, ์ŠคํŠธ๋ฆผ์˜ ์ •์˜์—์„œ '์†Œ์Šค'๋ผ๋Š” ์šฉ์–ด๊ฐ€ ๋‚˜์™”๋Š”๋ฐ, ์ด๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

์˜ˆ์ œ์—์„œ์˜ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” menuList์ด๋‹ค.

๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” ์—ฐ์†๋œ ์š”์†Œ๋ฅผ ์ŠคํŠธ๋ฆผ์—๊ฒŒ ์ œ๊ณตํ•œ๋‹ค.

  1. ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์—ฐ์‚ฐ
    ์ŠคํŠธ๋ฆผ์— filter, map, limit, collect ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์—ฐ์‚ฐ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1) filter
๋žŒ๋‹ค๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„, ์ŠคํŠธ๋ฆผ์—์„œ ํŠน์ • ์š”์†Œ๋ฅผ ํ•„ํ„ฐ๋งํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 1000์นผ๋กœ๋ฆฌ๋ณด๋‹ค ์ ์€ ๋ฐ์ดํ„ฐ๋งŒ ์„ ํƒํ•˜๊ณ , ๋‚˜๋จธ์ง€๋Š” ์ œ์™ธ์‹œ์ผฐ๋‹ค.

2) map
๋žŒ๋‹ค๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค๋ฅธ ์š”์†Œ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฉ”๋‰ด์˜ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜ค๋Š” ์‹.

3) limit
์ •ํ•ด์ง„ ๊ฐœ์ˆ˜ ์ด์ƒ์˜ ์š”์†Œ๊ฐ€ ์ŠคํŠธ๋ฆผ์— ์ €์žฅ ์•ˆ๋˜๋„๋ก ์ŠคํŠธ๋ฆผ ํฌ๊ธฐ๋ฅผ ์ค„์˜€๋‹ค.

4) collect
๋‹ค๋ฅธ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ์‹.

filter, map, limit ์—ฐ์‚ฐ์€ ์„œ๋กœ ํŒŒ์ดํ”„๋ผ์ธ์„ ํ˜•์„ฑ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, collect๋Š” ํŒŒ์ดํ”„๋ผ์ธ์„ ์ฒ˜๋ฆฌํ•ด์„œ ๋‹ค๋ฅธ ํ˜•ํƒœ๋ฆ ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

collect๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ์ถœ๋ ฅ ๊ฒฐ๊ณผ๊ฐ€ ์žˆ๋‹ค.

limit๋กœ ์š”์†Œ๋ฅผ ์ œ์™ธ ์‹œ์ผœ๋„, ์ŠคํŠธ๋ฆผ ์ถœ๋ ฅ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์€ ์—†๋‹ค.

์ŠคํŠธ๋ฆผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ํ•„ํ„ฐ๋ง/์ถ”์ถœ/์ถ•์†Œ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ ๋„ ํŒŒ์ดํ”„๋ผ์ธ์„ ๋” ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.


์ŠคํŠธ๋ฆผ๊ณผ ์ปฌ๋ ‰์…˜

์ปฌ๋ ‰์…˜๊ณผ ์ŠคํŠธ๋ฆผ์˜ ๊ณตํ†ต์ ์€ ์—ฐ์†๋œ ์š”์†Œ ํ˜•์‹์˜ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.

์—ฐ์†๋œ๋‹ค๋ผ๋Š” ๊ฑด ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฐ’์— ์ ‘๊ทผํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ฐจ์ด์ ์€ ๋ฌด์—‡์ผ๊นŒ๋‚˜

์ŠคํŠธ๋ฆผ๊ณผ ์ปฌ๋ ‰์…˜์˜ ์ฐจ์ด์  1: ๋ฐ์ดํ„ฐ๋ฅผ ์–ธ์ œ ๊ณ„์‚ฐํ•˜๋Š”๊ฐ€?

๋„ทํ”Œ๋ฆญ์Šค๋‚˜ ์œ ํŠœ๋ธŒ๋ฅผ ๋ณผ ๋•Œ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋น„์Šค๋ฅผ ๋ณธ๋‹ค๊ณ  ์–˜๊ธฐ๋ฅผ ํ•œ๋‹ค.

๊ทธ ๋•Œ ๊ทธ ์ŠคํŠธ๋ฆฌ๋ฐ์ด ์ŠคํŠธ๋ฆผ์ด๋‹ค.

์˜์ƒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ์žฌ์ƒํ•  ๋•Œ, ๋’ค์—๋Š” ์•„์ง ๋‹ค ๋‚ด๋ ค ๋ฐ›์ง€๋Š” ์•Š์•˜์ง€๋งŒ ๋ฏธ๋ฆฌ ๋ฐ›์€ ์•ž์ชฝ ํ”„๋ ˆ์ž„๋ถ€ํ„ฐ ์žฌ์ƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๋งŒ์•ฝ 3์‹œ๊ฐ„์งœ๋ฆฌ ์˜ํ™”๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ๋ดค๋‹ค๋ฉด ์ŠคํŠธ๋ฆฌ๋ฐ ๋ณด๋‹ค๋Š” ์‹œ๊ฐ„์ด ์กฐ๊ธˆ ๋” ๊ฑธ๋ฆด ๊ฒƒ์ด๋‹ค.

์ปฌ๋ ‰์…˜

ํ˜„์žฌ ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ํฌํ•จํ•˜๋Š” ๋ชจ๋“  ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ.

์ปฌ๋ ‰์…˜์— ์ถ”๊ฐ€๋˜๊ธฐ ์ „์— ๋ชจ๋“  ์š”์†Œ๊ฐ€ ๊ณ„์‚ฐ๋˜์–ด์•ผ ํ•œ๋‹ค.

์ปฌ๋ ‰์…˜์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€/์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ŠคํŠธ๋ฆผ

์š”์ฒญํ•  ๋•Œ๋งŒ ์š”์†Œ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ณ ์ •๋œ ์ž๋ฃŒ๊ตฌ์กฐ.

์ŠคํŠธ๋ฆผ์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€/์‚ญ์ œ ํ•  ์ˆ˜ ์—†๋‹ค.

์ŠคํŠธ๋ฆผ์—์„œ๋Š” ์ƒ์‚ฐ์ž์™€ ์†Œ๋น„์ž๋ผ๋Š” ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•  ๋•Œ๋งŒ ๊ทธ ๋•Œ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๊ณ„์‚ฐํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ์ ์„ ๋ณด๊ณ  ๊ฒŒ์œผ๋ฅด๋‹ค๊ณ  ๋ง์„ ํ•œ๋‹ค.

์ปฌ๋ ‰์…˜์€ ๋ชจ๋“  ๊ฑธ ๊ณ„์‚ฐํ•ด์„œ ์ƒ์‚ฐ์ž ์ค‘์‹ฌ์œผ๋กœ ์ฐฝ๊ณ ๋ฅผ ๋‹ค ์ฑ„์›Œ ๋†“๋Š” ์Šคํƒ€์ผ์ด๋‹ค.

์†Œ๋น„์ž๋Š” ๋ช‡๊ฐœ ๋ฐ–์— ์•ˆ ํ•„์š”ํ•œ๋ฐ๋„ ๋ง์ด๋‹ค. ๋ถ€์ง€๋Ÿฐํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์†Œ๋น„์ž๋Š” ํ•˜์—ผ์—†์ด ์ฐฝ๊ณ ์˜ ๋‚ด์šฉ์„ ๋ด์•ผํ•œ๋‹ค.

๋”ฑ ํ•œ๋ฒˆ๋งŒ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค

๋ฐ˜๋ณต์ž์ฒ˜๋Ÿผ ์ŠคํŠธ๋ฆผ๋„ ํ•œ๋ฒˆ๋งŒ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋ฐ์ดํ„ฐ ์š”์†Œ๋Š” ํ•œ ๋ฒˆ ํƒ์ƒ‰๋˜๋ฉด ์†Œ๋น„๋œ๋‹ค.

    @Test
    void streamOneChance() {
        List<String> idols = Arrays.asList("์•„์ด์œ ", "์—์ŠคํŒŒ", "๋ฅด์„ธ๋ผํ•Œ");
        Stream<String> stream = idols.stream();
        stream.forEach(System.out::println);
        stream.forEach(System.out::println); // Error! stream has already been operated upon or closed 
    }

 

ํ…Œ์ŠคํŠธ ์˜ˆ์ œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋ฉด, ๋งˆ์ง€๋ง‰ ์ค„์—์„œ ์ŠคํŠธ๋ฆผ์„ ํ•œ๋ฒˆ๋” ์ถœ๋ ฅํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ, stream has already been operated upon or closed ๋ผ๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ŠคํŠธ๋ฆผ๊ณผ ์ปฌ๋ ‰์…˜์˜ ์ฐจ์ด์  2: ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌํ•˜๋Š”๊ฐ€?

์ปฌ๋ ‰์…˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ for-each ๊ฐ™์€ ๊ฑธ ์‚ฌ์šฉํ•ด์„œ ์ง์ ‘ ๋ฐ์ดํ„ฐ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•ด์•ผํ•œ๋‹ค.

์ด๋ฅผ ์™ธ๋ถ€ ๋ฐ˜๋ณต์ด๋ผ๊ณ  ํ•จ.

๋‚ด๋ถ€ ๋ฐ˜๋ณต์€, ์ŠคํŠธ๋ฆผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ๋ฐ˜๋ณต์„ ์•Œ์•„์„œ ๋‹ค ํ•˜๊ณ  ์–ด๋”˜๊ฐ€์— ์ €์žฅ๋„ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

    @Test
    void iteratorTest() {
        List<String> idols = Arrays.asList("์•„์ด์œ ", "์—์ŠคํŒŒ", "๋ฅด์„ธ๋ผํ•Œ");

        // 1. ์™ธ๋ถ€ ๋ฐ˜๋ณต
        List<String> photo = new ArrayList<>();
        Iterator<String> iterator = idols.iterator();
        while (iterator.hasNext()) {
            photo.add(iterator.next());
        }

        // 2. ๋‚ด๋ถ€ ๋ฐ˜๋ณต
        List<String> photo2 = idols.stream()
                .collect(Collectors.toList());
    }

 

๋‚ด๋ถ€ ๋ฐ˜๋ณต์„ ํ•˜๋ฉด ๋ญ๊ฐ€ ์ข‹์œผ๋ƒ.

์ž‘์—…์„ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋” ์ตœ์ ํ™”ํ•ด์„œ ๋‹ค์–‘ํ•œ ์ˆœ์„œ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋ฐ์ดํ„ฐ ํ‘œํ˜„๊ณผ ํ•˜๋“œ์›จ์–ด๋ฅผ ํ™œ์šฉํ•œ ๋ณ‘๋ ฌ์„ฑ ๊ตฌํ˜„์„ ์ž๋™์œผ๋กœ ์„ ํƒํ•œ๋‹ค.

๋ณ‘๋ ฌ์„ฑ์„ ์•Œ์•„์„œ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฝ์ด๋‚˜ ๋™๊ธฐํ™” ๋ฌธ์ œ ๋“ฑ์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 

์ฑ… ์˜ˆ์ œ๊ฐ€ ์ธ์ƒ ๊นŠ์—ˆ๋Š”๋ฐ,

์•„์ด์—๊ฒŒ ๋ฐ”๋‹ฅ์— ๋–จ์–ด์ง„ ์žฅ๋‚œ๊ฐ์„ ํ•˜๋‚˜ ํ•˜๋‚˜ ๋งํ•ด์ฃผ๋ฉด์„œ, ๊ทธ ๋‹ค์Œ์—” ์ด๊ฑฐ ์ •๋ฆฌํ•ด. ์ด๊ฑฐ ์ •๋ฆฌํ•ด. ํ•˜๋Š”๊ฑฐ๋ณด๋‹ค๋Š”

์•„์ด๊ฐ€ ํ•œ๋ฒˆ์— ์ •๋ฆฌํ•ด์„œ ์žฅ๋‚œ๊ฐ ์ƒ์ž๋ฅผ ์ฃผ๋ฉด ์–ผ๋งˆ๋‚˜ ์ข‹์„๊นŒ์— ๋Œ€ํ•œ ์˜ˆ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ๋‘ ์†์œผ๋กœ ํ•œ๋ฒˆ์— ์ •๋ฆฌ๋ฅผ ํ•˜๊ธฐ๋„ ํ•˜๊ณ  ์‹œ๊ฐ„๋„ ๋‹จ์ถ•๋˜๋‹ˆ๊นŒ, ๋‚ด๋ถ€ ๋ฐ˜๋ณต์ด ๋” ์ข‹๋‹ค๋Š”..

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

์ŠคํŠธ๋ฆผ์˜ ๋‚ด๋ถ€ ๋ฐ˜๋ณต์„ ์‹ ๊ฒฝ์„ ์•ˆ์จ๋„ ๋œ๋‹ค๋Š” ๊ฒƒ์€, ๋ฐ์ดํ„ฐ ์—ฐ์‚ฐ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ฏธ๋ฆฌ ์ •์˜ ๋˜์–ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

์•„์ด๊ฐ€ ์žฅ๋‚œ๊ฐ์„ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž„๊นŒ?

๊ทธ ์—ฐ์‚ฐ์„ ๋žŒ๋‹ค ํ‘œํ˜„์‹์œผ๋กœ ์ธ์ˆ˜๋กœ ๋ฐ›๊ณ , ๋™์ž‘ ํŒŒ๋ผ๋ฏธํ„ฐํ™”๋„ ํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

    @Test
    @DisplayName("์š”๋ฆฌ ํด๋ž˜์Šค๋ฅผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ")
    void sortStreamExample() {
        List<String> lowCalDishesName = menuList.stream()// menuList์—์„œ ์ŠคํŠธ๋ฆผ์„ ์–ป์–ด์˜ด
                .filter(dish -> dish.getCalories() < 1000)// ํŒŒ์ดํ”„๋ผ์ธ ์—ฐ์‚ฐ์„ ๋งŒ๋“ฆ. 1000์นผ๋กœ๋ฆฌ๋ณด๋‹ค ์ ์€ ์š”๋ฆฌ๋ฅผ ํ•„ํ„ฐ๋ง ํ•œ๋‹ค.
                .sorted(Comparator.comparing(Dish::getCalories))
                .map(Dish::getName)// ์š”๋ฆฌ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜จ๋‹ค
                .limit(2)
                .collect(Collectors.toList()); // ์ŠคํŠธ๋ฆผ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค๋ฅธ ๋ฆฌ์ŠคํŠธ๋กœ ์ €์žฅํ•œ๋‹ค๋Š” ๋œป์ด์ž–์Šด~
    }

 

์•„๊นŒ ๋ดค๋˜ ์˜ˆ์ œ๋ฅผ ํ•œ ๋ฒˆ ๋” ๊ฐ€์ ธ์™”๋‹ค.

์ด๋ฅผ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.

  1. filter, map, limit์€ ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ํŒŒ์ดํ”„๋ผ์ธ์„ ํ˜•์„ฑ
  2. collect๋กœ ํŒŒ์ดํ”„๋ผ์ธ์„ ์‹คํ–‰ ํ›„ ์ŠคํŠธ๋ฆผ์„ ๋‹ซ๋Š”๋‹ค.

filter, map, limit ๊ฐ™์€ ์—ฐ์‚ฐ์„ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
collect ๊ฐ™์ด ์ŠคํŠธ๋ฆผ์„ ๋‹ซ๋Š” ์—ฐ์‚ฐ์„ ์ตœ์ข… ์—ฐ์‚ฐ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

์ค‘๊ฐ„ ์—ฐ์‚ฐ (intermediate operation)

filter, sorted ๊ฐ™์€ ์ค‘๊ฐ„ ์—ฐ์‚ฐ์ด ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ์—ฐ๊ฒฐ๋œ๋‹ค๋Š” ๊ฒƒ์€, ๊ฐ๊ฐ ๋‹ค๋ฅธ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ด ๊ฐ๊ฐ์˜ ์ŠคํŠธ๋ฆผ์ด ์—ฐ๊ฒฐ๋˜์–ด ํŒŒ์ดํ”„๋ผ์ธ์„ ํ˜•์„ฑํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋‹จ๋ง ์—ฐ์‚ฐ์ด ํŒŒ์ดํ”„๋ผ์ธํ™” ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

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

    @Test
    @DisplayName("์š”๋ฆฌ ํด๋ž˜์Šค๋ฅผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ")
    void shortCircuit() {
        List<String> lowCalDishesName = menuList.stream()
                .filter(dish -> {
                    System.out.println("filtering:"+dish.getName());
                    return dish.getCalories() < 1000;
                })
                .map( dish -> {
                    System.out.println("mapping:"+dish.getName());
                    return dish.getName();
                })
                .limit(2)
                .collect(Collectors.toList());
        System.out.println("results:"+ lowCalDishesName);
    }

 

์œ„ ์˜ˆ์ œ๋ฅผ ์‹คํ–‰์‹œ์ผœ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ๋œ๋‹ค.

filtering:๋‹ญ๊ฐ€์Šด์‚ด
mapping:๋‹ญ๊ฐ€์Šด์‚ด
filtering:์Šคํ”„
mapping:์Šคํ”„
results:[๋‹ญ๊ฐ€์Šด์‚ด, ์Šคํ”„]

 

์ด ์ฒ˜๋Ÿผ, filter์™€ map์€ ์„œ๋กœ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์ด์ง€๋งŒ, ํŒŒ์ดํ”„๋ผ์ธํ™”๊ฐ€ ๋˜์–ด ํ•œ ๊ณผ์ •์œผ๋กœ ๋ณ‘ํ•ฉ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. (๋ฃจํ”„ ํ“จ์ „)

์ค‘๊ฐ„ ์—ฐ์‚ฐ ์ข…๋ฅ˜

  1. filter
  2. map
  3. limit
  4. sorted
  5. distinct

์ตœ์ข… ์—ฐ์‚ฐ (terminal operation)

์ตœ์ข… ์—ฐ์‚ฐ์€ ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•˜๋Š” ์—ญํ• ์ด๋‹ค.

List, Integer, void ๊ฐ™์€ ์ŠคํŠธ๋ฆผ ์ด์™ธ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

    @Test
    void streamExample() {
        menuList.stream().forEach(System.out::println);
    }

 

forEach๋Š” System.out::println ๋žŒ๋‹ค๋ฅผ ์ ์šฉํ•ด์„œ void๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ตœ์ข… ์—ฐ์‚ฐ์œผ๋กœ ์“ฐ์˜€๋‹ค.

์ตœ์ข… ์—ฐ์‚ฐ ์ข…๋ฅ˜

  1. forEach: ์ŠคํŠธ๋ฆผ์˜ ๊ฐ ์š”์†Œ๋ฅผ ์†Œ๋น„ํ•˜๋ฉด์„œ ๋žŒ๋‹ค๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
  1. count: ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•จ
  1. collect: ์ŠคํŠธ๋ฆผ์œผ๋กœ List, Map, ์ •์ˆ˜ํ˜•์‹์˜ ์ปฌ๋ ‰์…˜์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•จ

์ŠคํŠธ๋ฆผ ์ด์šฉ ๊ณผ์ •

  • ์งˆ์˜๋ฅผ ์ˆ˜ํ–‰ํ•  ๋ฐ์ดํ„ฐ ์†Œ์Šค (์ปฌ๋ ‰์…˜)
  • ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์„ฑํ•  ์ค‘๊ฐ„ ์—ฐ์‚ฐ ์—ฐ๊ฒฐ (filter, map ๋“ฑ)
  • ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์„ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค ์ตœ์ข… ์—ฐ์‚ฐ (collect ๋“ฑ)

์ •๋ฆฌ

  • ์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ ์†Œ์Šค์—์„œ ์ถ”์ถœ๋œ ์—ฐ์† ์š”์†Œ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์—ฐ์‚ฐ์„ ์ง€์›
  • ๋‚ด๋ถ€ ๋ฐ˜๋ณต์„ ์ง€์›
  • ์ค‘๊ฐ„ ์—ฐ์‚ฐ๊ณผ ์ตœ์ข… ์—ฐ์‚ฐ์œผ๋กœ ๊ตฌ์„ฑ
  • ์ค‘๊ฐ„ ์—ฐ์‚ฐ: ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์„ฑํ•˜์ง€๋งŒ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๋Š” ์—†๋Š” ์—ฐ์‚ฐ
  • ์ตœ์ข… ์—ฐ์‚ฐ: ์ŠคํŠธ๋ฆผ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—ฐ์‚ฐ