📌 Stream은 데이터의 흐름을 다루는 API
- 데이터를 저장하는 것이 아니라, 데이터를 읽고 처리하는 흐름을 제공
- 한 번 사용하면 다시 사용할 수 없음 (소모성, 일회성)
List,Set,Map,Array등의 데이터 구조에서 사용 가능
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. 컬렉션(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();
✅ 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]
✅ 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(); }
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> → IntStreamStream<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();