
1. Java Stream API 이란?
Java Stream API는 Java 8에서 도입된 기능으로, 컬렉션(List, Set, Map 등)의 데이터를 함수형 스타일로 처리할 수 있도록 지원하는 기능입니다. Stream은 데이터 소스(컬렉션, 배열 등)를 처리하는 데 사용됩니다.
2. Stream API의 주요 특징
- 데이터 처리 중심: 컬렉션 요소를 반복하지 않고 함수형 프로그래밍 방식으로 데이터를 처리
- 연산 체이닝(Chaining): 여러 연산을 조합하여 선언적으로 처리 가능
- 내부 반복(Internal Iteration): 루프 없이 병렬 처리 최적화
- Immutable(불변성): 원본 데이터를 변경하지 않고 새로운 데이터를 생성
3. Stream 생성
스트림은 컬렉션, 배열, 또는 직접 값을 통해 생성할 수 있습니다.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
// 컬렉션에서 스트림 생성
List<String> list = Arrays.asList("apple", "banana", "cherry");
Stream<String> stream1 = list.stream();
stream1.forEach(System.out::println);
// 배열에서 스트림 생성
String[] array = {"dog", "cat", "bird"};
Stream<String> stream2 = Arrays.stream(array);
stream2.forEach(System.out::println);
// 직접 값으로 스트림 생성
Stream<String> stream3 = Stream.of("one", "two", "three");
stream3.forEach(System.out::println);
// 무한 스트림 생성
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);
infiniteStream.forEach(System.out::println);
}
}
4. Stream API 사용법(주요기능)
데이터의 필터링, 매핑, 정렬, 집계 등 다양한 작업을 간결하고 가독성 좋게 작성할 수 있습니다.
필터링(filter)
특정 조건을 만족하는 요소만 추출합니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
// 길이가 5 이상인 과일만 필터링
fruits.stream()
.filter(fruit -> fruit.length() > 5)
.forEach(System.out::println); // 출력: banana, cherry
// "apple"만 남김
fruits.stream()
.filter(s -> s.startsWith("a"))
.forEach(System.out::println); // 출력: apple
}
}
매핑(map)
요소를 다른 형태로 반환합니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "cherry");
// 모든 과일 이름을 대문자로 변환
fruits.stream()
.map(String::toUpperCase)
.forEach(System.out::println); // 출력: APPLE, BANANA, CHERRY
// 모든 요소를 2배 증가
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.map(n -> n * 2)
.forEach(System.out::println);
}
}
정렬(sorted)
요소를 정렬합니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("banana", "apple", "cherry");
// 오름차순 정렬(알파벳 순으로 정렬)
fruits.stream()
.sorted()
.forEach(System.out::println); // 출력: apple, banana, cherry
// 내림차순 정렬
fruits.stream()
.sorted((a, b) -> b.compareTo(a))
.forEach(System.out::println); // 출력: cherry, banana, apple
// 오름차순 정렬
List<Integer> numbers = Arrays.asList(1,2,3);
numbers.stream()
.sorted((a, b) -> a - b) // 또는 sorted((a, b) -> a.compareTo(b))
.forEach(System.out::println); // 출력: 1,2,3
// 내림차순 정렬
numbers.stream()
.sorted((a, b) -> b - a) // 또는 sorted((a, b) -> b.compareTo(a))
.forEach(System.out::println); // 출력: 3,2,1
}
}
특정 요소 선택 / 제외(limit(n) / skip(n))
특정 요소 선택 또는 제외 합니다.
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
Stream.of(1, 2, 3, 4, 5, 6)
.limit(3) // 처음 3개 요소만 선택
.forEach(System.out::println); // 출력: 1,2,3
Stream.of(1, 2, 3, 4, 5, 6)
.skip(3) // 처음 3개 요소 제외
.forEach(System.out::println); // 출력: 4,5,6
}
}
중복제거(distinct)
중복된 요소를 제거합니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "apple", "cherry");
// 문자열 중복 제거
fruits.stream()
.distinct()
.forEach(System.out::println); // 출력: apple, banana, cherry
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4);
// 정수 중복 제거
numbers.stream()
.distinct()
.forEach(System.out::println); // 출력: 1,2,3,4
}
}
집계 (count, sum, min, max, average)
요소의 개수, 합계, 최소값, 최대값, 평균 등을 계산합니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 합계 계산
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("Sum: " + sum); // 출력: Sum: 15
// 평균 계산
double average = numbers.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0);
System.out.println("Average: " + average); // 출력: Average: 3.0
}
}
리듀스(reduce)
요소를 결합하여 단일 결과를 생성합니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 모든 숫자의 곱 계산
int product = numbers.stream()
.reduce(1, (a, b) -> a * b);
System.out.println("Product: " + product); // 출력: Product: 120
// 모든 숫자의 합 계산
int sum = Stream.of(1, 2, 3, 4, 5).reduce(0, (a, b) -> a + b);
System.out.println(sum); // 15
}
}
조건검사(anyMatch, allMatch, noneMatch)
요소가 특정 조건을 만족하는지 검사합니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 모든 요소가 0보다 큰지 확인
boolean allPositive = numbers.stream()
.allMatch(n -> n > 0);
System.out.println("All positive: " + allPositive); // 출력: All positive: true
// 3보다 큰 요소가 하나라도 있는지 확인
boolean anyGreaterThanThree = numbers.stream()
.anyMatch(n -> n > 3);
// 출력: Any greater than 3: true
System.out.println("Any greater than 3: " + anyGreaterThanThree);
}
}
그룹화(groupingBy)
요소를 특정 기준으로 그룹화합니다.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
// 과일 이름의 길이로 그룹화
Map<Integer, List<String>> groupedByLength = fruits.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(groupedByLength);
// 출력: {5=[apple], 6=[banana, cherry], 4=[date]}
}
}
병렬 스트림(parallelStream)
병렬 처리를 통해 성능을 향상시킵니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
// 병렬 스트림으로 처리
fruits.parallelStream()
.forEach(System.out::println); // 순서가 보장되지 않음
}
}
5. Stream 활용 예제
짝수만 필터링 후 제곱 값 리스트 생성
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> result = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println(result); // [4, 16, 36]
}
}
문자열 리스트에서 가장 긴 단어 찾기
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry", "watermelon");
String longestWord = words.stream()
.max(Comparator.comparingInt(String::length))
.orElse("No words");
System.out.println(longestWord); // watermelon
}
}
특정 키워드를 포함하는 개수 구하기
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
long count = Stream.of("java", "javascript", "python", "c++")
.filter(s -> s.contains("java"))
.count();
System.out.println(count); // 2
}
}
forEach, count, collect 사용
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
Stream.of("A", "B", "C").forEach(System.out::println); // 출력: A, B, C
long count = Stream.of(1, 2, 3, 4, 5).count();
System.out.println(count); // 출력: 5
// 스트림에서 List 저장
List<String> list = Stream.of("A", "B", "C").collect(Collectors.toList());
System.out.println(list);
}
}
6. 정리
Java의 Stream API는 컬렉션 데이터를 처리하는 데 매우 강력한 도구입니다. 위의 예제들은 Stream의 주요 기능을 보여주며, 이를 활용하면 데이터를 효과적으로 처리하면서 코드를 더 간결하고 가독성 있게 작성할 수 있습니다. 상황에 맞게 적절한 기능을 선택하여 사용하면 됩니다. 또한 병렬 스트림을 활용하면 성능 최적화도 가능합니다.
'CS&기타' 카테고리의 다른 글
| [HTTP] Chunked Transfer Encoding (0) | 2025.03.02 |
|---|---|
| [HTTP] HyperText Transfer Protocol (0) | 2025.03.02 |
| [JAVA] 정규식 사용 정리 (0) | 2025.02.20 |
| [JAVA] Stream API Collect 메소드 (0) | 2025.02.20 |
| [JAVA] Checked Exception과 Unchecked Exception 차이점 (0) | 2025.02.13 |
| [Webassembly] C++ to Javascript(Javascript to C++) 함수 호출 (0) | 2024.08.11 |
| [Webassembly] Emscripten 사용하여 Webassembly 컴파일 (0) | 2024.08.06 |
| [MySQL] ERROR 1044 (42000): Access denied for user 'user'@'localhost' to database 'userdb' 에러 해결 방법 (0) | 2024.07.31 |