백준 5597 과제 안 내신 분 문제를 풀다가 stream에서 특정 범위의 정수를 생성하는 메서드가 생각이 났다.
시도 했다가 다양한 것을 알게 되어서 포스트로 남긴다.
IntStream과 LongStream은 지정된 범위의 연속된 정수를 스트림으로 생성해서 반환하는 range(), rangeClosed()를 가지고 있다.
IntStream IntStream.range(int begin, int end) //end 포함 x
IntStream IntStream.rangeClosed(int begin, int end) //end 포함
이는 IntStream으로 반환되기 때문에 우리가 사용하기 위해서는 배열이나 리스트로 변환을 해야한다. 나는 리스트의 삭제를 사용하기 위해 ArrayList<Integer>로 변환을 원해서 아래와 같이 변환을 하였다.
ArrayList<Integer> nums = (ArrayList<Integer>) IntStream.rangeClosed(1, 30).boxed().toList();
그러나, 이렇게 하니 ImmutableCollections을 ArrayList로는 캐스팅할 수 없다는 에러가 발생하였다.
Exception in thread "main" java.lang.ClassCastException: class java.util.ImmutableCollections$ListN cannot be cast to class java.util.ArrayList (java.util.ImmutableCollections$ListN and java.util.ArrayList are in module java.base of loader 'bootstrap')
UnsupportedOperationExcetpion
이 발생하였다.List<Integer> nums = IntStream.rangeClosed(1, 30).boxed().toList();
nums.remove(nums.indexOf(n));
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
at java.base/java.util.ImmutableCollections$AbstractImmutableList.remove(ImmutableCollections.java:258)
왜 이런 문제가 발생했는지 검색 결과 아래와 같은 내용을 찾을 수 있었다.
Before using this or converting old code, we should note that there is an important difference between these examples. The new
Stream.toList()
returns an unmodifiableArrayList
, whereCollectors.toList()
returns a modifiableArrayList
. I think this is probably the right decision as we should favor immutability whenever possible. If we need a mutable list, we can always use the pre-Java 16 way. Just be careful when updating old code to this new syntax, this small difference may cause anUnsupportedOperationExcetpion
to be thrown if the list ends up being modified elsewhere.
https://todd.ginsberg.com/post/java-16/stream-tolist/
toList()
를 사용하는 것이 아니라, collect(Collectors.toList())
를 사용해야 한다.List<Integer> nums = IntStream.rangeClosed(1, 30).boxed().collect(Collectors.toList());
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class B5597_과제안내신분 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<Integer> nums = IntStream.rangeClosed(1, 30).boxed().collect(Collectors.toList());
for (int i = 0; i < 28; i++) {
int n = sc.nextInt();
nums.remove(nums.indexOf(n));
}
Collections.sort(nums);
System.out.println(nums.get(0));
System.out.println(nums.get(1));
}
}