List를 Array로 Array를 List로 변환

  • Java
  • 2021년 5월 27일

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



1. 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문을 작성하는게 편할 수도 있다.



2. 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 로 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() 을 이용해야 한다.

Tags :

Related Posts

[WSL2] 포트포워딩과 window에서 workbench로 접속하기

[WSL2] 포트포워딩과 window에서 workbench로 접속하기

WSL2를 이용하여 개발을 진행서 외부에서 접근하고 싶거나, 배포를 위해 접근하고 싶을 수가 있는데, 문제가 되는 것이 WSL2는 VM과 같은 환경이라 별도의 IP를 갖는다는 점이다. 그러면 포트포워딩을 하면 되지 않느냐라고 할 수 있는데 맞다 포트포워딩을 하면된다 하지만 재부팅을 할때마다 변경되는 IP에 매번 포트 포워딩을 할 수 없는 노릇이기에 Powershell 파일을 이용하여 재부팅마다 wsl2의 ip를 잡아 특정 포트를 포트포워딩 하는 방법을 남기려고 한다....

Read More
제네릭

제네릭

  • Java
  • 2021년 2월 24일

제네릭은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법으로 컴파일 시에 더 많은 버그를 탐지할 수 있도록해 코드의 안전성을 더한다. C++의 템플릿과 처리 과정이나 방법의 차이점이 존재하지만 타입을 제거기술이라는 개념에서는 비슷하다고 볼 수 도 있다. Java 제네릭 컴파일타임에 에러를 검출할 수 있찌만 실제 동작코드는 제네릭을 사용하지 않을때와 동일해 성능도 동일하다. static 변수는 모든 객체가 공유하고, 모든 타입은 Object를 상속해야 하기 때문에 원시형 타입이 사용이 불가능 하다. C++ 템플릿 : 사용하지 않으면 컴파일을 하지 않는다. 컴파일러는 각각 타입에 대해 별도의 템플릿 코드를 생성하기 때문에, static변수를 공유하지 않고, 원시형 타입이 사용가능하다. 1. 장점 강력한 타입 체크 : 런타임이 아닌 컴파일 타임에 에러를 출력한다. 편한 캐스팅 : Object로 선언하여 (Integer) 와 같이 캐스팅을 하지 않아도 컴파일러에 의해 자동으로 형변환이 이루어진다. 코드의 재사용성이 높아진다. (코드 중복 최소화) 2. 제네릭 사용법 다음과 같이 Object형 배열을 갖는 ArrayList를 만들어 Integer형 배열로 사용하려고 하는데 String을 넣고 사용한다면 컴파일 타임에는 에러가 발생하지 않는데 런타임시 에러가 발생하게 된다....

Read More
PointRee 프로젝트 3 - back 개발환경 셋팅과 db설계

PointRee 프로젝트 3 - back 개발환경 셋팅과 db설계

IntelliJ를 이용해서 pointRee폴더 내에 back폴더를 생성해주고 여기에 spring boot 2.4로 프로젝트를 시작했다. dependency는 위와 같이 추가해주었다. 1. db설계 포인트의 유효기간을 처음에 생각을 했었으나 db설계와 구현과정에 있어 많은 시간이 생각보다 소요될 것 같아 일단 유효기간이 없다고 생각하고 설계를 진행했다. 완성후 다른곳에 문제가 없다면 차차 추가할 생각이다....

Read More