<aside> 📌 - 컬렉션 팩토리 사용하기
</aside>
자바에서는 적은 요소를 포함하는 리스트를 어떻게 만들까?
// 다음 방법은 세 문자열을 저장하는데도 많은 코드가 필요하다.
List<String> friends = new ArrayList<>();
friends.add("Raphael");
friends.add("Olivia");
friends.add("Thibaut");
다음처럼 Arrays.asList()
팩토리 메서드를 이용해 코드를 줄일 수 있지만, 고정 크기의 리스트이기 때문에 요소를 갱신할 수는 잇지만 새 요소를 추가하거나 삭제하려면 Unsupported OperationException이 발생한다.
//
List<String> friends
= Arrays.asList("Raphael", "Olivia ", "Thibaut");
//
List<String> friends = Arrays.asList("Raphael", "Olivia");
friends.set(0, "Rechard");
friends.add("Thibaut");
내부적으로 고정된 크기의 변환할 수 있는 배열로 구현되었기 때문에 이와같은 일이 일어난다.
리스트를 인수로 받는 HashSet 생성자를 사용하거나, 스트림 API로 해결할 수 있다.
// 리스트를 인수로 받는 HashSet 생성자
Set<String> friends
= new HashSet<>(Arrays.asList("Raphael", "Olivia","Thibaut"));
// 스트림 API 사용
Set<String> friends
= Stream.of("Raphael", "Olivia","Thibaut")
.collect(Collector.toSet());
하지만 두 방법 모두 매끄럽지 못하며 불필요한 객체 할당을 필요로 한다.
List.of
팩토리 메서드를 이용하면 간단하게 리스트를 만들 수 있다.
List<String> friends = List.of("Raphael", "Olivia","Thibaut");
하지만 마찬가지로 변경할 수 없는 리스트이기 때문에 add()
나 set()
메서드를 사용할 수 없다.
이런 제약이 무조건 나쁜 것은 아니다. 컬렉션이 의도치 않게 변하는 것을 막을 수 있기 때문이다.
하지만 요소 자체가 변하는 것을 막을 수 있는 방법은 없다.
즉, 리스트는 변경 가능한 자료형이기 때문에, 리스트 자체에 대한 참조가 변경되지 않더라도 해당 리스트의 내용을 직접 변경할 수 있습니다. 이는 리스트가 가변하다는 의미입니다. 리스트에 요소를 추가하거나 제거하면 리스트가 변경됩니다.
<aside> ❓ Q. 어떤 상황에서 새로운 컬렉션 팩토리 메서드 대신 스트림 api를 사용해 리스트를 만드는지 궁금 A.
데이터 변환 및 필터링
스트림 API는 강력한 변환 및 필터링 연산을 제공합니다. 예를 들어, 데이터의 일부만 선택하거나 특정 조건을 만족하는 요소만 필터링할 수 있습니다.
List<String> filteredList = myList.stream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
병렬 처리
스트림 API는 병렬 처리를 효과적으로 지원합니다. 대량의 데이터를 처리할 때, 멀티코어 프로세서에서 작업을 분산시켜 성능을 향상시킬 수 있습니다.
List<String> parallelList = myList.parallelStream()
.map(String::toUpperCase)
.collect(Collectors.toList());
데이터 그룹화 및 분할
스트림 API를 사용하면 데이터를 그룹화하거나 분할하는 작업을 쉽게 수행할 수 있습니다.
Map<Integer, List<String>> groupedByLength
= myList
.stream()
.collect(Collectors.groupingBy(String::length));
매핑 및 리듀싱
스트림 API는 매핑 및 리듀싱 작업을 지원합니다. 데이터를 특정 속성으로 매핑하거나, 모든 요소를 하나로 리듀스할 수 있습니다.
int totalLength = myList.stream()
.map(String::length)
.reduce(0, Integer::sum);
지연 평가
스트림 연산은 지연 평가를 지원하며, 필요한 경우에만 계산이 이루어집니다. 이는 불필요한 계산을 피하고 성능을 최적화하는 데 도움이 됩니다.
Stream<String> stream
= myList.stream().filter(s -> s.length() > 3);
</aside>