์ž๋ฐ” - Stream

Psjยท2025๋…„ 2์›” 20์ผ
0

F-lab

๋ชฉ๋ก ๋ณด๊ธฐ
1/4

Stream์ด๋ž€?

๐Ÿ“Œ Stream์€ ๋ฐ์ดํ„ฐ์˜ ํ๋ฆ„์„ ๋‹ค๋ฃจ๋Š” API

  • ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ํ๋ฆ„์„ ์ œ๊ณต
  • ํ•œ ๋ฒˆ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ (์†Œ๋ชจ์„ฑ, ์ผํšŒ์„ฑ)
  • List, Set, Map, Array ๋“ฑ์˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

Stream API ๊ธฐ๋ณธ ๊ตฌ์กฐ

List<String> list = Arrays.asList("apple", "banana", "cherry");

// 1. ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ โ†’ 2. ์ค‘๊ฐ„ ์—ฐ์‚ฐ(filter, map ๋“ฑ) โ†’ 3. ์ตœ์ข… ์—ฐ์‚ฐ(collect, forEach ๋“ฑ)
List<String> result = list.stream()
                          .filter(s -> s.startsWith("b")) // 'b'๋กœ ์‹œ์ž‘ํ•˜๋Š” ์š”์†Œ๋งŒ ์„ ํƒ
                          .map(String::toUpperCase)       // ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜
                          .sorted()                       // ์ •๋ ฌ
                          .collect(Collectors.toList());  // ๋ฆฌ์ŠคํŠธ๋กœ ๋ณ€ํ™˜

System.out.println(result); // ์ถœ๋ ฅ: [BANANA]

์ŠคํŠธ๋ฆผ ์ƒ์„ฑ๋ฐฉ๋ฒ• (์ƒ์„ฑ-์ค‘๊ฐ„์—ฐ์‚ฐ-์ตœ์ข…์—ฐ์‚ฐ)

1. ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ ๋˜๋Š” ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ

1. ์ปฌ๋ ‰์…˜(List, Set)์—์„œ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream(); // ์ผ๋ฐ˜ ์ŠคํŠธ๋ฆผ

2. ๋ฐฐ์—ด์—์„œ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜

String[] arr = {"A", "B", "C"};
Stream<String> stream = Arrays.stream(arr);

3. Stream.of() ๋กœ ์ƒ์„ฑ

Stream<String> stream = Stream.of("a", "b", "c");

4. ์ˆซ์žํ˜• ์ŠคํŠธ๋ฆผ(IntStream, LongStream, DoubleStream)

IntStream intStream = IntStream.range(1, 6); // 1~5

5. ๋นˆ ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ

Stream<String> emptyStream = Stream.empty();

2. ์ค‘๊ฐ„ ์—ฐ์‚ฐ (Intermediate Operations)

โœ… 1) filter(Predicate<T\>) - ์กฐ๊ฑด์— ๋งž๋Š” ์š”์†Œ๋งŒ ํ•„ํ„ฐ๋ง

Predicate<T> ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„ ์ฐธ๊ฑฐ์ง“์œผ๋กœ ๋ฆฌํ„ดํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง

List<String> list = Arrays.asList("apple", "banana", "cherry", "blueberry");

List<String> filteredList = list.stream()
                                .filter(s -> s.startsWith("b"))
                   .collect(Collectors.toList());

System.out.println(filteredList); // ์ถœ๋ ฅ: [banana, blueberry]

โœ… 2) map(Function<T, R>) - ์š”์†Œ ๋ณ€ํ™˜

Function<T, R> ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„ ์กฐ๊ฑด์— ๋งž๊ฒŒ ๋ณ€ํ˜•ํ›„ ๋ณ€ํ˜•๋œ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง

List<String> names = Arrays.asList("john", "peter", "anna");

List<String> upperCaseNames = names.stream()
                                   .map(String::toUpperCase)
                            .collect(Collectors.toList());

System.out.println(upperCaseNames); // ์ถœ๋ ฅ: [JOHN, PETER, ANNA]

โœ… 3) sorted() - ์ •๋ ฌ

List<Integer> numbers = Arrays.asList(5, 2, 9, 1, 3);

List<Integer> sortedNumbers = numbers.stream()
                                     .sorted()
                                     .collect(Collectors.toList());

System.out.println(sortedNumbers); // ์ถœ๋ ฅ: [1, 2, 3, 5, 9]

โœ… 4) distinct() - ์ค‘๋ณต ์ œ๊ฑฐ

List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3, 4);

List<Integer> distinctNumbers = numbers.stream()
                                       .distinct()
                                       .collect(Collectors.toList());

System.out.println(distinctNumbers); // ์ถœ๋ ฅ: [1, 2, 3, 4]

โœ… 5) limit(n), skip(n) - ๊ฐœ์ˆ˜ ์ œํ•œ ๋ฐ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50);

List<Integer> limitedNumbers = numbers.stream()
                                      .limit(3) // ์ฒ˜์Œ 3๊ฐœ๋งŒ ์„ ํƒ
                                      .collect(Collectors.toList());

List<Integer> skippedNumbers = numbers.stream()
                                      .skip(2) // ์ฒ˜์Œ 2๊ฐœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ
                                      .collect(Collectors.toList());

System.out.println(limitedNumbers); // ์ถœ๋ ฅ: [10, 20, 30]
System.out.println(skippedNumbers); // ์ถœ๋ ฅ: [30, 40, 50]

3. ์ตœ์ข…์—ฐ์‚ฐ

โœ… 1) collect(Collectors.toList()) - ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ณ€ํ™˜

List<String> result = list.stream()
                          .filter(s -> s.length() > 3)
                          .collect(Collectors.toList());

โœ… 2) forEach() - ๋ชจ๋“  ์š”์†Œ ์ถœ๋ ฅ

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

โœ… 3) count() - ์š”์†Œ ๊ฐœ์ˆ˜ ๋ฐ˜ํ™˜

long count = list.stream().count();

โœ… 4) anyMatch(), allMatch(), noneMatch() - ์กฐ๊ฑด ๊ฒ€์‚ฌ

boolean hasApple = list.stream().anyMatch(s -> s.equals("apple")); // ํ•˜๋‚˜๋ผ๋„ ๋งŒ์กฑํ•˜๋ฉด true
boolean allStartWithA = list.stream().allMatch(s -> s.startsWith("a")); // ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋ฉด true
boolean noneStartWithZ = list.stream().noneMatch(s -> s.startsWith("z")); // ํ•˜๋‚˜๋„ ๋งŒ์กฑํ•˜์ง€ ์•Š์œผ๋ฉด true

โœ… 5) reduce() - ๋ˆ„์  ์—ฐ์‚ฐ

int sum = numbers.stream().reduce(0, Integer::sum); // ๋ชจ๋“  ์ˆซ์ž ๋”ํ•˜๊ธฐ
System.out.println(sum); // ์ถœ๋ ฅ: ํ•ฉ๊ณ„ ๊ฐ’

๐Ÿ“Œ :: (๋ฉ”์„œ๋“œ ์ฐธ์กฐ) ์—ฐ์‚ฐ์ž ์„ค๋ช…

๋งํฌ ํ™•์ธ

 public List<CourseInfoDto> getCourseDayOfWeek(DayOfWeek dayOfWeek) {
    // TODO: ๊ณผ์ œ ๊ตฌํ˜„ ๋ถ€๋ถ„
    List<Course> courses = courseRepository.getCourseDayOfWeek(dayOfWeek);
    return courses.stream().map(CourseInfoDto::new).toList();
  }

Stream<Integer> ์™€ IntStream์˜ ์ฐจ์ด

1. ๊ธฐ๋ณธ ๊ฐœ๋…

  • Stream<Integer>: Stream<T>์˜ ์ œ๋„ค๋ฆญ ๋ฒ„์ „์œผ๋กœ, Integer ๊ฐ์ฒด๋ฅผ ์š”์†Œ๋กœ ๊ฐ€์ง€๋Š” ์ŠคํŠธ๋ฆผ.
  • IntStream: ๊ธฐ๋ณธํ˜• int ๊ฐ’์„ ๋‹ค๋ฃจ๋Š” ํŠน์ˆ˜ํ•œ ์ŠคํŠธ๋ฆผ.

3. ์‚ฌ์šฉ๋ฒ• ์ฐจ์ด

Stream<Integer>

  • Integer ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฃจ๋ฏ€๋กœ Stream<Integer>์—์„œ ์ œ๊ณตํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ Stream ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
  • ํ•˜์ง€๋งŒ sum(), average() ๊ฐ™์€ ์ˆซ์ž ์—ฐ์‚ฐ์„ ํ•˜๋ ค๋ฉด mapToInt() ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ IntStream์œผ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•จ.
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
int sum = integerStream.mapToInt(Integer::intValue).sum();  // IntStream์œผ๋กœ ๋ณ€ํ™˜ ํ›„ ํ•ฉ๊ณ„ ๊ณ„์‚ฐ
System.out.println(sum); // 15

IntStream

  • sum(), average(), max(), min() ๊ฐ™์€ ์ˆซ์ž ์—ฐ์‚ฐ ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ”๋กœ ์ œ๊ณตํ•จ.
  • boxed()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Stream<Integer>๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ.
IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
int sum = intStream.sum(); // ๋ฐ”๋กœ ํ•ฉ๊ณ„ ๊ณ„์‚ฐ ๊ฐ€๋Šฅ
System.out.println(sum); // 15

4. ์ƒ์„ฑ ๋ฐฉ์‹

Stream<Integer> ์ƒ์„ฑ

Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);

IntStream ์ƒ์„ฑ

IntStream intStream1 = IntStream.of(1, 2, 3, 4, 5);
IntStream intStream2 = IntStream.range(1, 6);  // 1๋ถ€ํ„ฐ 5๊นŒ์ง€ (6์€ ํฌํ•จ๋˜์ง€ ์•Š์Œ)
IntStream intStream3 = IntStream.rangeClosed(1, 5); // 1๋ถ€ํ„ฐ 5๊นŒ์ง€ ํฌํ•จ

5. ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•

Stream<Integer> โ†’ IntStream

Stream<Integer> integerStream = Stream.of(1, 2, 3);
IntStream intStream = integerStream.mapToInt(Integer::intValue);

IntStream โ†’ Stream<Integer>

IntStream intStream2 = IntStream.of(1, 2, 3);
Stream<Integer> boxedStream = intStream2.boxed();
profile
Software Developer

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

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด