[Java] IntStream

์กฐ๋ฏผ๊ฒฝยท2024๋…„ 12์›” 27์ผ

Java

๋ชฉ๋ก ๋ณด๊ธฐ
2/8

๐Ÿ˜ฎ [Programmers] ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์—ฐ์Šต > ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์ž…๋ฌธ > ์ง์ˆ˜์˜ ํ•ฉ
์ด ๋ฌธ์ œ๋ฅผ ํ’€๋‹ค๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ์ฝ”๋“œ๋ฅผ ๋ดค๋Š”๋ฐ, stream์„ ์ด์šฉํ•œ ์ฝ”๋“œ์˜€๋‹ค. ๊ทธ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  stream์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋‘๋ฉด ์ข‹์„ ๊ฑฐ ๊ฐ™์•„ ์“ด ํฌ์ŠคํŒ…์ด๋‹ค!




๐Ÿ“Œ IntStream


โœ”๏ธ IntStream์— ๋Œ€ํ•˜์—ฌ

  • IntStream์€ Java 8์—์„œ ๋„์ž…๋œ Stream API์˜ ์ผ์ข…์œผ๋กœ, intํ˜• ์›์‹œ ํƒ€์ž…์— ํŠนํ™”๋œ ์ŠคํŠธ๋ฆผ์ž…๋‹ˆ๋‹ค.

  • IntStream์€ ์ •์ˆ˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ŠคํŠธ๋ฆผ์œผ๋กœ, ์ผ๋ฐ˜์ ์ธ Stream<Integer>๋ณด๋‹ค ๋” ํšจ์œจ์ ์ด๋ฉฐ ์ˆซ์ž์™€ ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ ์—ฐ์‚ฐ(ํ•„ํ„ฐ๋ง, ๋งคํ•‘, ์ง‘๊ณ„ ๋“ฑ)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

  • ํŠนํžˆ ๋ฐ˜๋ณต ์ž‘์—…์ด๋‚˜ ์ •์ˆ˜ ์—ฐ์‚ฐ์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ณ  ๊ฐ€๋…์„ฑ์ด ๋†’์•„์ง€๊ณ , Java 8 ์ด์ƒ์˜ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ์„ ์ตํžˆ๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.



โœ”๏ธ IntStream ์ƒ์„ฑ ๋ฐฉ๋ฒ•

  1. IntStream.range(startInclusive, endExclusive)

    • startInclusive๋ถ€ํ„ฐ endExclusive๊นŒ์ง€ ์—ฐ์†๋œ ์ •์ˆ˜ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ (๋์€ ํฌํ•จ๋˜์ง€ ์•Š์Œ).

      IntStream.range(1, 5).forEach(System.out::println);
      // ์ถœ๋ ฅ: 1, 2, 3, 4
  2. IntStream.rangeClosed(startInclusive, endInclusive)

    • startInclusive๋ถ€ํ„ฐ endInclusive๊นŒ์ง€ ์—ฐ์†๋œ ์ •์ˆ˜ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ (๋ ํฌํ•จ).

      IntStream.rangeClosed(1, 5).forEach(System.out::println);
      // ์ถœ๋ ฅ: 1, 2, 3, 4, 5
  1. ๋ฐฐ์—ด ๋˜๋Š” ์ปฌ๋ ‰์…˜์—์„œ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ
int[] array = {1, 2, 3, 4, 5};
IntStream.of(array).forEach(System.out::println);
// ์ถœ๋ ฅ: 1, 2, 3, 4, 5
  1. generate ๋ฉ”์„œ๋“œ๋กœ ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ

    • ํŠน์ • ๊ฐ’์„ ๊ณ„์† ๋ฐ˜๋ณตํ•˜๊ฑฐ๋‚˜, ์กฐ๊ฑด ์—†์ด ๊ฐ’์„ ์ƒ์„ฑ.

      IntStream.generate(() -> 1).limit(5).forEach(System.out::println);
      // ์ถœ๋ ฅ: 1, 1, 1, 1, 1
  2. iterate ๋ฉ”์„œ๋“œ๋กœ ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ

    • ์ดˆ๊ธฐ๊ฐ’๊ณผ ๋ฐ˜๋ณต ๊ทœ์น™์„ ์„ค์ •.

      IntStream.iterate(0, n -> n + 2).limit(5).forEach(System.out::println);
      // ์ถœ๋ ฅ: 0, 2, 4, 6, 8



โœ”๏ธ ์ฃผ์š” ๋ฉ”์„œ๋“œ

  1. filter

    • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ๋งŒ ๋‚จ๊น€.

      IntStream.range(1, 10)
         .filter(x -> x % 2 == 0)
         .forEach(System.out::println);
      // ์ถœ๋ ฅ: 2, 4, 6, 8
  2. map

    • ๊ฐ ์š”์†Œ๋ฅผ ๋ณ€ํ™˜ํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ.

      IntStream.range(1, 5)
         .map(x -> x * x)
         .forEach(System.out::println);
      // ์ถœ๋ ฅ: 1, 4, 9, 16
  1. reduce

    • ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋ฅผ ์ง‘๊ณ„(๋ˆ„์ )ํ•˜์—ฌ ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋กœ ์ถ•์†Œ.
      int sum = IntStream.range(1, 5)
         .reduce(0, Integer::sum);
       System.out.println(sum);
      // ์ถœ๋ ฅ: 10 (1 + 2 + 3 + 4)
  2. sum

    • ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋”ํ•จ.
      int sum = IntStream.rangeClosed(1, 5).sum();
       System.out.println(sum);
      // ์ถœ๋ ฅ: 15
  3. average

    • ํ‰๊ท ์„ ๊ณ„์‚ฐํ•˜์—ฌ OptionalDouble ๋ฐ˜ํ™˜.
      IntStream.rangeClosed(1, 5)
         .average()
         .ifPresent(System.out::println);
      // ์ถœ๋ ฅ: 3.0
  4. max, min

    • ์ตœ๋Œ€๊ฐ’๊ณผ ์ตœ์†Œ๊ฐ’์„ ๊ตฌํ•จ.
      int max = IntStream.range(1, 10).max().orElseThrow();
       int min = IntStream.range(1, 10).min().orElseThrow();
       System.out.println("Max: " + max + ", Min: " + min);
       // ์ถœ๋ ฅ: Max: 9, Min: 1
  5. distinct

    • ์ค‘๋ณต ์š”์†Œ๋ฅผ ์ œ๊ฑฐ.
      IntStream.of(1, 2, 2, 3, 4, 4, 5)
         .distinct()
         .forEach(System.out::println);
      // ์ถœ๋ ฅ: 1, 2, 3, 4, 5
  6. sorted

    • ์š”์†Œ๋ฅผ ์ •๋ ฌ.
      IntStream.of(5, 3, 1, 4, 2)
         .sorted()
         .forEach(System.out::println);
      // ์ถœ๋ ฅ: 1, 2, 3, 4, 5
  7. boxed

    • ์›์‹œ ํƒ€์ž… ์ŠคํŠธ๋ฆผ์„ Stream<Integer>๋กœ ๋ณ€ํ™˜.

      IntStream.range(1, 5)
         .boxed()
         .map(x -> x + 10)
         .forEach(System.out::println);
      // ์ถœ๋ ฅ: 11, 12, 13, 14



โœ”๏ธ ํŠน์ง•๊ณผ ์žฅ์ 

  1. ํšจ์œจ์„ฑ

    • IntStream์€ ์›์‹œ ํƒ€์ž…(int) ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ•์‹ฑ/์–ธ๋ฐ•์‹ฑ ๋น„์šฉ์ด ์—†์–ด์„œ ์„ฑ๋Šฅ์ด ๋” ์ข‹๋‹ค.
    • Stream<Integer>๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ ๋ฐ CPU ์ž์›์„ ์ ๊ฒŒ ์†Œ๋น„.
  2. ์ง€์—ฐ ์—ฐ์‚ฐ

    • ๋Œ€๋ถ€๋ถ„์˜ ๋ฉ”์„œ๋“œ(filter, map, sorted ๋“ฑ)๋Š” ์ง€์—ฐ ์‹คํ–‰๋œ๋‹ค. ์ฆ‰, ์ตœ์ข… ์—ฐ์‚ฐ(sum, forEach ๋“ฑ)์ด ํ˜ธ์ถœ๋  ๋•Œ ์‹คํ–‰.
  3. ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ

    • .parallel()์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๋‹จํžˆ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

      int sum = IntStream.rangeClosed(1, 1000)
         .parallel()
         .sum();
       System.out.println(sum);
       // ์ถœ๋ ฅ: 500500



โœ”๏ธ ๋‹จ์ 

IntStream์€ int ํƒ€์ž…์— ํŠนํ™”๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด ์ถ”๊ฐ€ ๋ณ€ํ™˜์ด ํ•„์š”ํ•˜๋‹ค(mapToObj, boxed ๋“ฑ).
์š”์•ฝ
IntStream์€ ์ •์ˆ˜ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ŠคํŠธ๋ฆผ์œผ๋กœ, ๋‹ค์–‘ํ•œ ์—ฐ์‚ฐ(ํ•„ํ„ฐ๋ง, ๋งคํ•‘, ์ง‘๊ณ„ ๋“ฑ)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
ํŠนํžˆ ๋ฐ˜๋ณต ์ž‘์—…์ด๋‚˜ ์ •์ˆ˜ ์—ฐ์‚ฐ์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ณ  ๊ฐ€๋…์„ฑ์ด ๋†’์•„์ง‘๋‹ˆ๋‹ค.
Java 8 ์ด์ƒ์˜ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ์„ ์ตํžˆ๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.




๐Ÿ“Œ IntStream ํ™œ์šฉ ์ฝ”๋“œ ์˜ˆ์ œ


[Programmers] ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์—ฐ์Šต > ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์ž…๋ฌธ > ์ง์ˆ˜์˜ ํ•ฉ

๐Ÿ’ป ์™„์„ฑ ์ฝ”๋“œ

import java.util.stream.IntStream;
class Solution {
    public int solution(int n) {
        return IntStream.rangeClosed(0, n)
            .filter(e -> e % 2 == 0)
            .sum();
    }
}



๐Ÿ“‹ ์ฝ”๋“œ ๋ถ„์„

import java.util.stream.IntStream; // IntStream ์‚ฌ์šฉ์„ ์œ„ํ•ด ์ŠคํŠธ๋ฆผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž„ํฌํŠธ

๐Ÿ’ก IntStream์€ Java์˜ Stream API ์ค‘ ์ •์ˆ˜์— ํŠนํ™”๋œ ์ŠคํŠธ๋ฆผ ํด๋ž˜์Šค์ด๋‹ค.

โ˜‘๏ธ rangeClosed์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์—ฐ์†๋œ ์ •์ˆ˜ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•œ๋‹ค.

โ˜‘๏ธ ์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ•๋ ฅํ•˜๊ณ  ๊ฐ„๊ฒฐํ•œ ๋ฐฉ์‹์œผ๋กœ, ํ•„ํ„ฐ๋ง, ๋งคํ•‘, ์ง‘๊ณ„ ๋“ฑ์˜ ์ž‘์—…์„ ์ง€์›ํ•œ๋‹ค.



๐Ÿ“ ์ฃผ์š” ๋ถ€๋ถ„ ์„ค๋ช…

class Solution {
    public int solution(int n) {
        return IntStream.rangeClosed(0, n)  // 0๋ถ€ํ„ฐ n๊นŒ์ง€ ํฌํ•จํ•˜๋Š” ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ
            .filter(e -> e % 2 == 0)       // ์ง์ˆ˜๋งŒ ํ•„ํ„ฐ๋ง (e % 2 == 0์ธ ์š”์†Œ๋งŒ ํ†ต๊ณผ)
            .sum();                        // ๋‚จ์€ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ๋”ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜
    }
}

1. IntStream.rangeClosed(0, n)

  • 0๋ถ€ํ„ฐ n๊นŒ์ง€์˜ ์—ฐ์†๋œ ์ •์ˆ˜๋ฅผ ํฌํ•จํ•˜๋Š” ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•œ๋‹ค.

  • ์˜ˆ๋ฅผ ๋“ค์–ด, n = 5๋ผ๋ฉด ์ŠคํŠธ๋ฆผ์€ [0, 1, 2, 3, 4, 5]๋กœ ์ƒ์„ฑ๋œ๋‹ค.

2. .filter(e -> e % 2 == 0)

  • ๋žŒ๋‹ค์‹ e -> e % 2 == 0:

    • ์ŠคํŠธ๋ฆผ์˜ ๊ฐ ์š”์†Œ๋ฅผ e๋กœ ๋ฐ›์•„์™€ e % 2 == 0 ์กฐ๊ฑด์ด true์ธ ๊ฒฝ์šฐ๋งŒ ํ†ต๊ณผ์‹œํ‚จ๋‹ค.
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ง์ˆ˜๋งŒ ๋‚จ๊ธด๋‹ค.

    • ์˜ˆ๋ฅผ ๋“ค์–ด, ์ŠคํŠธ๋ฆผ์ด [0, 1, 2, 3, 4, 5]๋ผ๋ฉด ํ•„ํ„ฐ ๊ฒฐ๊ณผ๋Š” [0, 2, 4]์ด๋‹ค.

3. .sum()

  • ์ŠคํŠธ๋ฆผ์— ๋‚จ์•„ ์žˆ๋Š” ๋ชจ๋“  ์š”์†Œ๋ฅผ ๋”ํ•œ๋‹ค.

  • ์˜ˆ๋ฅผ ๋“ค์–ด, [0, 2, 4]์ด๋ผ๋ฉด ๊ฒฐ๊ณผ๋Š” 0 + 2 + 4 = 6์ž…๋‹ˆ๋‹ค.

4. ๋ฐ˜ํ™˜๊ฐ’

  • ๊ณ„์‚ฐ๋œ ์ง์ˆ˜ ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€