Java

[Java] new ArrayList<>() 와 Arrays.asList() 차이점 및 비교

토발자 2022. 12. 26. 18:27
반응형

지금까지 List를 생성할 때 대부분 new ArrayList<>()를 사용했었다.

회사에서 다른 분들의 코드를 보다가 Arrays.asList()를 이용한 부분이 있었고 참고해서 사용했는데, 차이점을 정확히 알고 싶어 정리하고자 한다.

 


1. 다른 class, 다른 return type

  • 다른 class : new ArrayList<>()와 Arrays.asList()는 다음과 같이 class가 다르다.
// new ArrayList<>()
import java.util.ArrayList;

// Arrays.asList()
import java.util.Arrays;

 

  • new ArrayList<>()는 ArrayList를 Arrays.asList()는 Arrays의 정적 클래스인 ArrayList를 리턴한다.
    • 아래는 Arrays 클래스의 asList이다.
// Arrays.class
@SafeVarargs
public static <T> List<T> asList(T... a) {
    return new Arrays.ArrayList(a);
}

 

 

2. 원소의 추가/삭제 가능 여부

결론부터 정리하면 다음과 같다.

 

  원소의 추가/삭제 set 사용
new ArrayList<>() 가능 가능
Arrays.asList() 불가능 가능

 

2-1. new ArrayList<>()부터 먼저 정리해보자.

import java.util.ArrayList;

public class ArrayListTest {
    public static void main(String[] args) {
    	// ArrayList 생성
        ArrayList<String> fruits = new ArrayList<>();
        
        // add() method로 원소 추가
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add(0, "Mango");
        fruits.add("Strawberry");

        // set() method로 특정 인덱스의 값을 대체
        fruits.set(0, "Melon");

        System.out.println(fruits); // [Melon, Apple, Banana, Strawberry]
    }
}

add() 메서드는 기본적으로 리스트의 가장 끝에 원소를 추가한다.

별도로 인덱스를 지정하면 해당 인덱스에 값이 추가되고 이후의 인덱스에 있는 값들은 한 칸씩 밀린다.

 

다시 하나씩 살펴보면 Apple과 Banana가 ArrayList fruits에 순서대로 추가된다.

Mango가 0번째 인덱스에 추가되면서 Apple과 Banana는 각각 인덱스 한 칸씩 밀리게 된다.

그리고 Strawberry가 맨 뒤에 추가된다.

마지막으로 특정 인덱스의 값을 대체하는 set() 메서드를 통해 0번째 인덱스에 있는 Mango가 Melon으로 변경된다.

 

 

2-2. Arrays.asList()에 대해 정리해보자.

Arrays.asList()는 javadoc 와 클래스에서 메서드 설명을 찾아보면 다음과 같은 내용을 찾을 수 있다.

Returns a fixed-size list backed by the specified array.

해석해보면 특정한 배열에 의해 백업된 고정된 크기의 List를 반환한다는 내용이다.

 

말 그대로 Arrays.asList()는 고정된 List로 원소를 추가하거나 삭제할 수 없다.

 

하지만 List의 원소 값을 변경할 수는 있다.

원소 값 변경 방법에는 2가지가 있다.

 

2-2-1. set() 메서드 사용

set() 메서드를 통해 특정 인덱스의 원소 값을 변경할 수 있다.

 

import java.util.ArrayList;
import java.util.Arrays;
 
 
public class ArrayAsListTest {
   public static void main(String[] args) {
      String[] fruits = {"Apple", "Banana", "Mango"};
      List<String> list = Arrays.asList(fruits);
      
      System.out.println(list); // [Apple, Banana, Mango]
      System.out.println(fruits); // [Apple, Banana, Mango]
      
      list.set(2, "Melon"); // set() method로 두 번째 인덱스 값 변경
      
      System.out.println(list); // [Apple, Banana, Melon]
      System.out.println(fruits); // [Apple, Banana, Melon]
   }
}

 

set() 메서드를 이용해 두 번째 인덱스의 원소를 변경했다.

list에 담겨있는 두 번째 인덱스의 원소를 변경했는데 원본 배열인 fruits의 데이터도 함께 변경되었다.

 

List는 내부 구조가 배열로 만들어져 있어 asList()를 사용해서 반환되는 List도 배열을 갖게 된다.
이 때, asList()를 사용해 List 객체를 만들 때 새로운 배열 객체를 만드는 것이 아니라, 원본 배열의 주소값을 가져오게 된다.
따라서 asList()를 사용해서 내용을 수정하면 원본 배열도 함께 수정된다.

 

 

2-2-2. 원본 배열 변경

import java.util.ArrayList;
import java.util.Arrays;
 
 
public class ArrayAsListTest {
   public static void main(String[] args) {
      String[] fruits = {"Apple", "Banana", "Mango"};
      List<String> list = Arrays.asList(fruits);
      
      System.out.println(list); // [Apple, Banana, Mango]
      System.out.println(fruits); // [Apple, Banana, Mango]
      
      fruits[2] = "Melon"; // 원본 배열 fruits의 두 번째 인덱스 값 변경
      
      System.out.println(list); // [Apple, Banana, Melon]
      System.out.println(fruits); // [Apple, Banana, Melon]
   }
}

 

두 번째 방법은 원본 배열인 String[] fruits 배열을 변경시키는 방법이다.

 

Arrays.asList()는 String[] fruits(특정한 배열)를 백업할 때 주소값을 가져온다.

따라서 위와 같이 String[] fruits가 변경되면 list도 변경된다.(참고로 new ArrayList<>()를 사용하면 새로운 주소값를 할당한다.)

 

만약 원소를 추가/삭제하고 싶다면 new ArrayList로 변환해준 뒤 add() 메서드를 사용하면 된다.

import java.util.ArrayList;
import java.util.Arrays;
 
 
public class ArrayAsListTest {
   public static void main(String[] args) {
      String[] fruits = {"Apple", "Banana", "Mango"};
      List<String> arrayList = new ArrayList<>(Arrays.asList(fruits));
      
      arrayList.add("Melon");
      
      System.out.println(arrayList); // [Apple, Banana, Mango, Melon]

   }
}

 

다음과 같이 ArrayList 생성자는 java.util.Arrays.ArrayList의 상위 클래스인 Collection type도 받아들일 수 있기 때문에 가능하다.

 

 


new ArrayList<>()와 Arrays.asList()에 대해서 조금은 정리가 된 것 같다.

 

마지막으로 간단히 정리를 해보자면

new ArrayList<>() : 원본 배열의 데이터가 변경되면 안되거나 새로운 주소값으로 할당해야할 때
Arrays.asList() : 원소의 개수가 제한되어 사용되어야 하거나, 변할 필요가 없을 때

이렇게 구분해 사용하면 좋을 것 같다.

 

반응형