프로젝트/예산 관리 어플리케이션 (개인)

Stream을 List로 변환하는 방법들의 차이

가을맛 2023. 12. 14. 20:50

왜 그래야하는데??

 

 

프로젝트 리펙토링을 하면서 SonarLint 로 코드 정적 분석을 하고 있다. Stream.collect(Collectors.toList()) 말고 Stream.toList()로 변경하라고 해서 아무 생각없이 하고 바꾸고 있다가... 문득 왜 그래야하는지 궁금해져서 한번 찾아봤다.

 

Stream을 List로 변환하는 3가지 방법

 

// (1) 가변 리스트 
List<String> list1 = Stream.of("A", "B", "C")
                           .collect(Collectors.toList()); 

// (2) 가변 리스트
List<String> list2 = Stream.of("A", "B", "C")
                           .collect(Collectors.toUnmodifiableList()); 
                           
// (3) 불변 리스트
List<String> list3 = Stream.of("A", "B", "C").toList();  // Java 16 ~

 

 

결론부터 말하자면 3번 방식 (=Stream.toList())로 생성 시 불변 리스트를 생성해주기 때문이다.

 

그럼 여기서 드는 의문 : 2번 방식 ( unmodifiableList )은 왜 가변리스트인가? 

이름부터 '수정할수 없는 리스트' 인게 뭔가 불변일 것 같아 보인다. 하지만 UnmodifiableList는 진짜 불변 리스트가 아니다.

 

 

[Java] UnmodifiableList는 진짜 불변 리스트가 아니다

목차 들어가기 전에 불변성이 강조되는 객체지향 프로그래밍의 특성상 자바에서도 UnmodifiableList라는 클래스가 존재한다(물론 List 뿐만 아니라 Map과 Set도 존재한다). UnmodifiableList라는 이름에 걸

colabear754.tistory.com

 

위 블로그의 설명에 의하면 Collectors.toUnmodifiableList() 는 List를 불변 뷰로 한번 감싸서 반환한다. 때문에 원본 컬렉션의 불변성을 보장하지는 않는다.


대부분의 API에서는 List 를 생성한 이후 update할 일이 없으므로, 불변성을 보장하는 방식 (3번) 으로 리스트를 만드는 게 합리적일 것이다. 하지만 리스트 생성 이후 내용물을 수정해야한다면 3번이 아닌 1번 방식을 사용해야한다.