developer tip

List.of와 Arrays.asList의 차이점은 무엇입니까?

optionbox 2020. 9. 1. 07:27
반응형

List.of와 Arrays.asList의 차이점은 무엇입니까?


Java 9는 목록에 대한 새로운 팩토리 메소드를 도입했습니다 List.of.

List<String> strings = List.of("first", "second");

이전 옵션과 새 옵션의 차이점은 무엇입니까? 즉, 이것의 차이점은 무엇입니까?

Arrays.asList(1, 2, 3);

이:

List.of(1, 2, 3);

Arrays.asList에 의해 반환 된 목록에있는 동안 변경 가능한 목록을 반환 List.of이다 불변 :

List<Integer> list = Arrays.asList(1, 2, null);
list.set(1, 10); // OK

List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException

Arrays.asList다음을 List.of수행하지 않는 동안 null 요소를 허용합니다 .

List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException

contains null과 다르게 작동합니다.

List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false

List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with NullPointerException

Arrays.asList전달 된 배열의보기를 반환하므로 배열의 변경 사항도 목록에 반영됩니다. 들어 List.of이 사실이 아니다 :

Integer[] array = {1,2,3};
List<Integer> list = Arrays.asList(array);
array[1] = 10;
System.out.println(list); // Prints [1, 10, 3]

Integer[] array = {1,2,3};
List<Integer> list = List.of(array);
array[1] = 10;
System.out.println(list); // Prints [1, 2, 3]

사이의 차이 Arrays.asListList.of

JavaDocsStuart Marks (또는 이전 버전) 의이 강연참조하십시오 .

코드 예제에 다음을 사용하겠습니다.

List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);

구조적 불변성 (또는 : 수정 불가능)

구조적으로 변경 하려는 시도 List.ofUnsupportedOperationException. 여기에는 추가 , 설정제거같은 작업이 포함됩니다 . 그러나 목록에있는 개체의 내용을 변경할 수 있으므로 (개체가 변경 불가능하지 않은 경우) 목록이 "완전히 변경 불가능"하지 않습니다.

로 생성 된 수정 불가능한 목록의 운명과 동일 Collections.unmodifiableList합니다. 이 목록 만 원래 목록 보기 이므로 원래 목록을 변경하면 변경 될 수 있습니다.

Arrays.asList완전히 불변하지 않으며에 대한 제한이 없습니다 set.

listOf.set(1, "a");  // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a");  // modified unmodif! unmodif is not truly unmodifiable

마찬가지로 백업 배열을 변경하면 (보유하고있는 경우) 목록이 변경됩니다.

Structural immutability comes with many side-effects related to defensive coding, concurrency and security which are beyond the scope of this answer.

Null hostility

List.of and any collection since Java 1.5 do not allow null as an element. Attempting to pass null as an element or even a lookup will result in a NullPointerException.

Since Arrays.asList is a collection from 1.2 (the Collections Framework), it allows nulls.

listOf.contains(null);  // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null);  // allowed

Serialized form

Since List.of has been introduced in Java 9 and the lists created by this method have their own (binary) serialized form, they cannot be deserialized on earlier JDK versions (no binary compatibility). However, you can de/serialize with JSON, for example.

Identity

Arrays.asList internally calls new ArrayList, which guarantees reference inequality.

List.of depends on internal implementation. The instances returned can have reference equality, but since this is not guaranteed you can not rely on it.

asList1 == asList2; // false
listOf1 == listOf2; // true or false

Worth mentioning that lists are equal (via List.equals) if they contain the same elements in the same order, regardless of how they were created or what operations they support.

asList.equals(listOf); // true i.f.f. same elements in same order

Implementation (warning: details can change over versions)

If the number of elements in the list of List.of is 2 or less, the elements are stored in fields of a specialized (internal) class. An example is the list that stores 2 elements (partial source):

static final class List2<E> extends AbstractImmutableList<E> {
    private final E e0;
    private final E e1;

    List2(E e0, E e1) {
        this.e0 = Objects.requireNonNull(e0);
        this.e1 = Objects.requireNonNull(e1);
    }
}

Otherwise they are stored in an array in a similar fashion to Arrays.asList.

Time and Space efficiency

The List.of implementations which are field-based (size<2) perform slightly faster on some operations. As examples, size() can return a constant without fetching the array length, and contains(E e) does not require iteration overhead.

Constructing an unmodifiable list via List.of is also faster. Compare the above constructor with 2 reference assignments (and even the one for arbitrary amount of elements) to

Collections.unmodifiableList(Arrays.asList(...));

which creates 2 lists plus other overhead. In terms of space, you save the UnmodifiableList wrapper plus some pennies. Ultimately, the savings in the HashSet equivalent are more convincing.


Conclusion time: use List.of when you want a list that doesn't change and Arrays.asList when you want a list that can change (as shown above).


Let summarize the differences between List.of and Arrays.asList

  1. List.of can be best used when data set is less and unchanged, while Arrays.asList can be used best in case of large and dynamic data set.

  2. List.of take very less overhead space because it has field-based implementation and consume less heap space, both in terms of fixed overhead and on a per-element basis. while Arrays.asList take more overhead space because while initialization it creates more objects in heap.

  3. Collection returned by List.of is immutable and hence thread-safe while Collection returned by Arrays.asList is mutable and not thread safe. (Immutable collection instances generally consume much less memory than their mutable counterparts.)

  4. List.of doesn't allow null elements while Arrays.asList allows null elements.


Apart from the above answers there are certain operations on which both List::of and Arrays::asList differ:

+----------------------+---------------+----------+----------------+---------------------+
|      Operations      | SINGLETONLIST | LIST::OF | ARRAYS::ASLIST | JAVA.UTIL.ARRAYLIST |
+----------------------+---------------+----------+----------------+---------------------+
|          add         |       ❌       |     ❌    |        ❌       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|        addAll        |       ❌       |     ❌    |        ❌       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|         clear        |       ❌       |     ❌    |        ❌       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|        remove        |       ❌       |     ❌    |        ❌       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|       removeAll      |       ❗️       |     ❌    |        ❗️       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|       retainAll      |       ❗️       |     ❌    |        ❗️       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|      replaceAll      |       ❌       |     ❌    |        ✔️       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|          set         |       ❌       |     ❌    |        ✔️       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|         sort         |       ✔️       |     ❌    |        ✔️       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
|  remove on iterator  |       ❌       |     ❌    |        ❌       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
| set on list-iterator |       ❌       |     ❌    |        ✔️       |          ✔️          |
+----------------------+---------------+----------+----------------+---------------------+
  1. ✔️ means the method is supported
  2. ❌ means that calling this method will throw an UnsupportedOperationException
  3. ❗️ means the method is supported only if the method's arguments do not cause a mutation, e.g. Collections.singletonList("foo").retainAll("foo") is OK but Collections.singletonList("foo").retainAll("bar")throws an UnsupportedOperationException

More about Collections::singletonList Vs. List::of

참고URL : https://stackoverflow.com/questions/46579074/what-is-the-difference-between-list-of-and-arrays-aslist

반응형