toArray는 자주 까먹기 쉬운 API다. 핵심은 반환 타입이다. String[]가 필요한지, Integer[]가 필요한지, int[]가 필요한지에 따라 마지막 코드가 달라진다.
List를 참조 타입 배열로 바꾸기
List<String>을 String[]로 바꿀 때는 다음처럼 쓴다.
String[] result = list.toArray(new String[0]);
new String[0]은 반환 배열의 타입을 알려주는 역할이다.
List<Integer>를 Integer[]로 바꾸면 다음과 같다.
Integer[] result = list.toArray(new Integer[0]);
int[]가 필요할 때
List<Integer>에서 int[]를 만들 때는 toArray(new int[0])를 쓸 수 없다. 제네릭 컬렉션은 primitive 타입 배열을 직접 만들 수 없기 때문이다.
이때는 stream을 IntStream으로 바꾼 뒤 toArray()를 사용한다.
int[] result = list.stream()
.mapToInt(Integer::intValue)
.toArray();
객체 스트림에서 필드를 꺼낼 때도 같은 흐름이다.
int[] result = songs.stream()
.mapToInt(song -> song.index)
.toArray();
또는 먼저 Integer로 매핑한 뒤 mapToInt를 써도 된다.
int[] result = songs.stream()
.map(song -> song.index)
.mapToInt(Integer::intValue)
.toArray();
다만 바로 mapToInt(song -> song.index)가 더 짧다.
Stream.toList와 Collectors.toList
stream().toList()는 Java 16 이후 API다. 로컬 JDK가 17이어도 채점 환경이나 컴파일 타깃이 낮으면 인식되지 않을 수 있다.
프로그래머스에서 안전하게 가려면 다음처럼 쓴다.
List<Integer> list = stream.collect(Collectors.toList());
필요한 import는 다음이다.
import java.util.stream.Collectors;
반환 타입별 기억표
| 필요한 타입 | 코드 |
|---|---|
String[] | list.toArray(new String[0]) |
Integer[] | list.toArray(new Integer[0]) |
int[] | list.stream().mapToInt(Integer::intValue).toArray() |
객체 필드에서 int[] | list.stream().mapToInt(x -> x.field).toArray() |
| Java 8 호환 List | stream.collect(Collectors.toList()) |
실수 체크
- 필요한 반환 타입이
int[]인지Integer[]인지 먼저 확인했는가 - primitive 배열이면
mapToInt(...).toArray()를 썼는가 - 참조 타입 배열이면
new 타입[0]을 넣었는가 - 제출 환경이 애매하면
stream().toList()대신Collectors.toList()를 썼는가