List를 Array로 Array를 List로 변환

List와 Array간의 변환은 기본적으로 for문을 이용하여 하나하나 바꾸어주면 변환이 가능하다. 하지만 for이 아닌 stream api를 이용해서 더 간편하게 바꿀 수 있는 방법을 정리한다.



List에서 Array로 변환

1. List -> Object[]

List<Integer> integerList = new ArrayList<>();
List<String> stringList = new ArrayList<>();

Integer[] integerArr = integerList.toArray(new Integer[integerList.size()]);
String[] stringArr = stringList.toArray(new String[stringList.size()]);
Object[] objectArr = integerList.toArray();

List에서 Wrapper객체배열로 바꾸는 것은 List의 toArray()함수를 이용하면 쉽게 바꿀 수 있고 toArray()의 매개변수로 변환할 객체배열을 넘겨주면 해당 타입의 배열로 바꾸어 반환된다.

만일 매개변수없이 사용한다면 Object[]로 바꾸어 반환이 된다.


2. List -> primitive type[]

List<Integer> integerList = new ArrayList<>();

int[] arr1 = integerList.stream().mapToInt(Integer::intValue).toArray();
int[] arr2 = integerList.stream().mapToInt(x->x).toArray();   //위와 실행결과는 같다.

double[] arr3 = integerList.stream().mapToDouble(Integer::intValue).toArray();

int나 double, long과 같이 primitive 타입의 배열로 바꾸고 싶을때는 IntStream,DoubleStream,LongStream의 toArray()를 이용하면 원시타입배열로 바꿀 수 있다.

List를 stream으로 바꾼 후 mapToInt(),mapToDouble()…와 같은 스트림api의 함수를 이용해 해당타입의 Stream으로 변경할 수 있다. 위의 함수는 map과 동일하지만 결과물이 특정타입의 Stream으로 변환된다는 차이가 있다.


3. 다중 List -> 다중 primitive값 배열

//2차원
List<List<Integer>> list = new ArrayList<>();

int[][] arr2 = list.stream()
                .map(l -> l.stream()
                              .mapToInt(Integer::intValue)
                              .toArray())
                .toArray(int[][]::new);

//3차원
List<List<List<Integer>>> list = new ArrayList<>();

int[][][] arr3 = list.stream()
                .map( l1 -> l1.stream()
                        .map(l2 -> l2.stream()
                                        .mapToInt(Integer::intValue)
                                        .toArray())
                        .toArray(int[][]::new))
                .toArray(int[][][]::new);

다중 List를 다중 배열로 바꾸기 위해서는 map을 이용해서 계속 한 차원씩 줄이고, 1차원으로 줄여졌을때는 mapToInt를 이용해서 앞에서 설명한것 과 같이 만들어 주면 된다.

하지만 메서드 chaining이 복잡해져 헷갈릴 수 있기 때문에 for문을 작성하는게 편할 수도 있다.



Array 에서 List로 변환

◾1. Object[] -> List

Integer[] integerArr = new Integer[10];
String[] stringArr = new String[10];

List<Integer> integerList = Arrays.asList(integerArr);
List<String> stringList = Arrays.asList(stringArr);

Arrays의 asList()함수를 이용하면 래퍼객체 배열로 쉽게 변경이 가능하다.


◾2. primitive[] -> List

int[] integerArr = new int[10];
double[] doubleArr = new double[10];

List<Integer> integerList1 = Arrays.stream(integerArr).boxed().collect(Collectors.toList());
List<Integer> integerList2 = IntStream.of(integerArr).boxed().collect(Collectors.toList());

List<Double> doubleList = Arrays.stream(doubleArr).boxed().collect(Collectors.toList());

primitive타입을 Wrapper객체로 바꾸어 주어야 하기 때문에 특정타입의 Stream(ex. IntStream)에 있는 boxed() 메서드를 이용하는데 이함수는 IntStream에서 Stream<Integer>로 Wrapper객체로 감싸진 Stream으로 바꾸어주는 메서드이다.

boxed()를 사용하기 위해 Arrays.stream()으로 특정타입의 Stream으로 바꾸어주면 되고 boxed()로 바꾸어진 Stream을 collect메서드로 새로 list를 만들어 줄 수 있다.


IntStream의 boxed()메서드를 이용하기 위해 Arrays의 stream()을 이용해도 되고 IntStream의 of()를 이용해서 InstStream을 만들 수 있다.


◾3. 다중 primitive배열 -> 다중 List

//2차원
int[][] arr2 = new int[][]{{1,2},{2,3}};
List<List<Integer>> list2 = Arrays.stream(arr)
              .map(tmp -> IntStream.of(tmp)
                      .boxed()
                      .collect(Collectors.toList()))
              .collect(Collectors.toList());

//3차원
int[][][] arr3 = new int[][][]{{{1,2},{2,3}}};
List<List<List<Integer>>> list3 = Arrays.stream(arr3)
                .map(tmp -> Arrays.stream(tmp)
                        .map(tmp2 -> IntStream.of(tmp2)
                                .boxed()
                                .collect(Collectors.toList()))
                        .collect(Collectors.toList()))
                .collect(Collectors.toList());

다중 배열에서 List로 변환도 위에서 설명한 다중 List -> 다중 배열과 같이 map을 이용해 1차원이 될때까지 분해후 List로 만들어 주면된다.

여기서 IntStram.of()는 매개변수로 1차원 배열밖에 받지 않기 때문에 3차원을 2차원 Stream으로 바꾸기 위해서는 IntStram.of가 아니라 Arrays.stream()을 이용해야 한다.