-
Stream을 List로 변환하는 2가지의 방법(Collectors.toList(), Stream.toList())Back-End/Spring 2023. 4. 18. 06:46728x90
개요
사이드 프로젝트에서, 작성한 글에 대한 이미지 업로드 로직에서 이슈가 터지게 되었다.
사진 업로드 기능은 이미지를 업로드 창에 올리거나, 기존의 것을 삭제하거나, 업로드 창에 올린 것을 다시 삭제하는 등
다양한 경우의 수가 있어서 이를 잘 고려해서 설계해야한다.
우리는 2개의 배열을 두어 (업로드 할 이미지, 삭제 될 이미지) 서버로 전달받도록 하였고, 삭제할 이미지는
해당 포스트의 기존에 존재하던 이미지인 경우만 삭제하도록 구현하였다.
문제점
문제는 해당 메서드에서 발생했다.
해당 메서드는 List를 받아 element 1개를 제외한 List를 만들어 반환 해 주는 메서드인데
기존에는 주석처리 된 부분으로 코드 로직을 진행하였다.
하지만 java16 부터 등장한 toList() 메서드는 해당 메서드의 리턴 리스트 자료형이 unmodifiable하다고 한다.
따라서, 이 후 해당 리스트에 add 연산을 하고자 하면 해당 예외가 발생했다.
java.lang.UnsupportedOperationException: null at java.util.AbstractList.add(AbstractList.java:148) ~[na:1.8.0_201] at java.util.AbstractList.add(AbstractList.java:108) ~[na:1.8.0_201]
이유는, 우리가 toList() 메서드로 받는 arrayList 클래스는 AbstractList<E> 추상 클래스를 상속받는데,
해당 arrayList 클래스가 add 메서드를 override하지 않았기 때문에 추상클래스의 add 메서드가 그대로 호출이 되어
예외를 던지게 된 것이었다.
결과적으로, Collectors.toList() 메서드를 통해 modifiable한 arrayList를 사용하였고, 정상적으로 로직이 작동하였다.
하지만, Java 진영에서 Stream.toList() 를 권고하는 이유
람다와 스트림을 도입하게 된 java 8 버전부터 stream연산의 결과를 취합하여 리스트로 반환하는 종단연산인 .collect(Collectors.toList()) 를 사용할 수 있었다.
하지만 해당 메서드는 리턴되는 List가 수정이 가능(modifiable) 하다는 특징이 있어서, 메서드의 불변성을 지키기 위해 java10 에서 수정불가능한(unmodifiable) List 로 반환되도록 toUnmodifiableList() 가 새롭게 등장했다고 한다. 하지만 toUnmodfiableList() 는 이름이 장황해서, java16 에서는 이를 보완하기 위해 Stream.toList() 가 등장했다고 한다.
결과적으로 Collectors.toList() 메서드를 사용하긴 했지만, 해당 메서드를 사용하지 않는 방향으로 코드를 리팩토링 해 봐야 겠다.
'Back-End > Spring' 카테고리의 다른 글
Spring AOP가 적용된 커스텀 어노테이션 및 Bean 사용 시 유의점 (0) 2024.04.12 멀티 모듈 구현 시 발생했던 git 관련 이슈 (0) 2023.08.06 nGrinder를 활용한 어플리케이션 성능테스트 (0) 2023.01.06 Spring Rest docs를 활용한 API 명세를 openapi3를 활용하여 swagger로 변환하기 (0) 2022.12.13 Spring Security cors 이슈 (0) 2022.10.21