본문 바로가기

우테코/Level1

.collect(Collectors.toList()) vs Stream.toList()

>>문제 상황

 

.collect(Collectors.toList())와 .toList()는 스트림을 리스트로 바꾸어 주는 기능을 한다.

그러나, .collect(Collectors.toList())를 사용하니 SonarLint에서  Stream.toList()로 대체하라는 문구가 떴다.

 

순간 의문이 들었다. 기능적으로는 같은데 대체 두 collect 메서드 사이에 무슨 차이가 있지?


우선 이 두가지 메서드의 차이를 보자

Collectors.toList() vs Collectors.toUnmodifiableList()

 

Collectors.toList() : 만들어진 List가 변경 가능

Collectors.toUnmodifiableList() : 만들어진 List가 변경 불가능

//SonarLint 예시

List<String> list1 = Stream.of("A", "B", "C")
                           .collect(Collectors.toList()); // Noncompliant

List<String> list2 = Stream.of("A", "B", "C")
                           .collect(Collectors.toUnmodifiableList()); // Noncompliant

 

이 차이는 메서드 안에 내포되어 있으므로 쉽게 이해할 수 있다.

 

그리고 Java16부터 collect.(Collectors.toUnmodifiableList()) 보완하기 위해 나온 것이 Stream.toList()이다. 즉, .collect(Collectors.toUnmodifiableList())처럼 Stream.toList()도 불변 리스트를 반환하기에 안전성이 더 좋다. 실제로 Stream.toList()는 다음처럼 소스코드가 짜여져 있다.

 

@SuppressWarnings("unchecked")
    default List<T> toList() {
        return (List<T>) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())));
    }

 

 

그렇다면 Collectors.toUnmodifiableList()와 Stream.toList()는 똑같을까?

 

한가지 차이가 있다.

바로 Null의 허용여부이다.

 

Collectors.toUnmodifiableList()는 null을 허용하지 않는다. null값이 담겨있으면 NPE가 터진다.

그러나, Stream.toList()는 null값을 허용한다.


그럼 정리해보자

  반환 리스트 수정 가능 여부 null 허용여부
.collect(Collectors.toList()) O O
.collect(Collectors.toUnmodifiableList()) X X
Stream.toList() X O