자바8 Stream 기능 이해하기
Java 8에서 소개된 Stream API는 컬렉션 데이터를 더욱 효율적으로 처리할 수 있는 기능입니다. 병렬 처리를 쉽게 구현할 수 있어 성능 향상에 큰 도움이 되며, 간결한 코드로 복잡한 연산을 수행할 수 있습니다. 이 글에서는 Java 8의 Stream 기능을 예제를 통해 상세하게 살펴보겠습니다.
1. Stream 기본 개념:
스트림(Stream)은 '데이터의 흐름'을 의미합니다. 컬렉션의 데이터를 스트림으로 변환하여 연속된 데이터 처리 작업을 수행할 수 있습니다. Stream API는 함수형 프로그래밍 스타일을 지원하며, 데이터를 변환하거나 필터링하는 데 사용할 수 있는 다양한 메소드를 제공합니다.
2. Stream 생성:
스트림은 다양한 소스로부터 생성할 수 있습니다. 주로 컬렉션, 배열, I/O 채널 등이 사용됩니다. 예를 들어 List 객체에서 스트림을 생성하는 방법은 다음과 같습니다.
List<String> names = Arrays.asList("John", "Jane", "Mike", "Sara");
Stream<String> nameStream = names.stream();
3. 중간 연산:
스트림에서 수행되는 중간 연산은 스트림의 요소를 필터링, 정렬, 변환 등의 작업을 수행합니다. 중간 연산은 여러 개 연결할 수 있으며, 연산 결과로 새로운 스트림을 반환합니다. 중간 연산의 예로는 filter, map, sorted 등이 있습니다.
예제: 이름 목록에서 길이가 4보다 작은 이름만 필터링하기
Stream<String> shortNames = nameStream.filter(name -> name.length() < 4);
예제: 이름 목록에서 모든 이름을 대문자로 변환하기
Stream<String> upperCaseNames = nameStream.map(String::toUpperCase);
예제: 이름 목록을 알파벳순으로 정렬하기
Stream<String> sortedNames = nameStream.sorted();
4. 최종 연산:
최종 연산은 스트림을 종료하고 결과를 반환합니다. 최종 연산의 예로는 forEach, toArray, reduce, collect 등이 있습니다.
예제: 필터링된 이름 목록 출력하기
shortNames.forEach(System.out::println);
예제: 이름 목록을 배열로 변환하기
String[] nameArray = nameStream.toArray(String[]::new);
예제: 이름 목록을 하나의 문자열로 결합하기
Optional<String> combinedName = nameStream.reduce((name1, name2) -> name1 + ", " + name2);
예제: 이름 목록을 Map으로 변환하기
Map<String, Integer> nameLengthMap = nameStream.collect(Collectors.toMap(name -> name, String::length));
5. 병렬 스트림:
스트림 API는 멀티코어 프로세서의 장점을 쉽게 활용할 수 있도록 병렬 스트림을 지원합니다. 병렬 스트림은 여러 스레드에서 동시에 데이터 처리 작업을 수행할 수 있습니다.
예제: 병렬 스트림으로 이름 목록의 길이 합 구하기
int totalLength = names.parallelStream().mapToInt(String::length).sum();
결론:
Java 8의 Stream API는 컬렉션 데이터를 효율적으로 처리하는 강력한 기능입니다. 중간 연산과 최종 연산을 이용해 복잡한 데이터 처리 작업을 간결한 코드로 작성할 수 있으며, 병렬 스트림을 통해 성능 향상을 누릴 수 있습니다. 함수형 프로그래밍 스타일을 지원하므로, 람다 표현식과 메서드 참조를 자유롭게 활용하여 코드 가독성을 높일 수 있습니다. 이러한 기능들을 잘 활용하면, Java에서 데이터 처리 작업을 더욱 쉽고 간결하게 구현할 수 있습니다.