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.asList
와List.of
JavaDocs 및 Stuart Marks (또는 이전 버전) 의이 강연 을 참조하십시오 .
코드 예제로 다음을 사용하겠습니다.
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
구조적 불변성 (또는 : 수정 불가능)
구조적으로 변경 하려는 시도 List.of
는 UnsupportedOperationException
. 여기에는 추가 , 설정 및 제거 와 같은 작업이 포함됩니다 . 그러나 목록에있는 개체의 내용을 변경할 수 있으므로 (개체가 변경 불가능하지 않은 경우) 목록이 “완전히 변경 불가능”하지 않습니다.
로 생성 된 수정 불가능한 목록의 운명과 동일 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
마찬가지로 백업 배열을 변경하면 (보유하고있는 경우) 목록이 변경됩니다.
구조적 불변성은이 답변의 범위를 벗어난 방어 코딩, 동시성 및 보안과 관련된 많은 부작용을 동반합니다.
무적의 적대감
List.of
Java 1.5 이후의 모든 컬렉션 null
은 요소로 허용되지 않습니다 . null
요소 또는 조회 로 전달하려고 시도 하면 NullPointerException
.
이후 Arrays.asList
1.2에서 컬렉션 (컬렉션 프레임 워크), 그것이 허용 null
들.
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
직렬화 된 형식
때문에 List.of
자바 (9) 도입 및이 방법에 의해 생성 된리스트는 자신의 (바이너리) 직렬화 된 형식을 가지고있다, 그들은 이전 JDK 버전 (NO 역 직렬화 할 수없는 바이너리 호환성 ). 그러나 예를 들어 JSON을 사용하여 역 직렬화 할 수 있습니다.
정체
Arrays.asList
내부적으로를 호출 new ArrayList
하여 참조 부등식을 보장합니다.
List.of
내부 구현에 따라 다릅니다. 반환 된 인스턴스는 참조 동등성을 가질 수 있지만 이것이 보장되지 않으므로 신뢰할 수 없습니다.
asList1 == asList2; // false
listOf1 == listOf2; // true or false
목록 List.equals
이 생성 된 방법이나 지원하는 작업에 관계없이 동일한 순서로 동일한 요소를 포함하는 경우 목록은 동일합니다 (를 통해 ).
asList.equals(listOf); // true i.f.f. same elements in same order
구현 (경고 : 세부 정보는 버전에 따라 변경 될 수 있음)
목록의 요소 수가 List.of
2 개 이하인 경우 요소는 특수 (내부) 클래스의 필드에 저장됩니다. 예는 2 개의 요소 (부분 소스)를 저장하는 목록입니다.
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);
}
}
그렇지 않으면 .NET과 유사한 방식으로 배열에 저장됩니다 Arrays.asList
.
시간 및 공간 효율성
List.of
필드 기반 (크기 <2)이다 구현은 어떤 작업이 약간 빠르게 수행한다. 예를 들어, size()
배열 길이를 가져 오지 않고 상수를 반환 할 수 contains(E e)
있으며 반복 오버 헤드가 필요하지 않습니다.
를 통해 수정할 수없는 목록을 생성 List.of
하는 것도 더 빠릅니다. 위의 생성자를 2 개의 참조 할당 (임의의 요소에 대한 할당 포함)과 비교하여
Collections.unmodifiableList(Arrays.asList(...));
2 개의 목록과 다른 오버 헤드를 생성합니다. 공간 측면에서 UnmodifiableList
래퍼와 약간의 동전 을 절약합니다 . 궁극적으로 HashSet
동등한 비용 절감 이 더 설득력이 있습니다.
결론 시간 : List.of
변경되지 않는 Arrays.asList
목록을 원할 때 와 변경할 수있는 목록을 원할 때 사용합니다 (위 그림 참조).
답변
List.of 와 Arrays.asList 의 차이점을 요약 해 보겠습니다.
-
List.of
데이터 세트가 적고 변경되지 않은Arrays.asList
경우 가장 잘 사용할 수있는 반면, 크고 동적 데이터 세트의 경우 가장 잘 사용할 수 있습니다. -
List.of
필드 기반 구현이 있기 때문에 오버 헤드 공간을 매우 적게 차지하고 고정 오버 헤드와 요소 별 기준 모두에서 더 적은 힙 공간을 사용합니다.Arrays.asList
초기화하는 동안 힙에 더 많은 객체를 생성하기 때문에 더 많은 오버 헤드 공간 을 차지합니다. -
에서 반환 된 컬렉션
List.of
은 변경 불가능하므로 스레드로부터 안전하지만에서 반환 된 컬렉션Arrays.asList
은 변경 가능하며 스레드로부터 안전하지 않습니다. (불변 컬렉션 인스턴스는 일반적으로 가변 인스턴스보다 훨씬 적은 메모리를 사용합니다.) -
List.of
허용하지 않는 널 동안 요소를Arrays.asList
허용 널 (null) 요소를.
답변
외에도 위의 답변에서 두 가지 모두에 대해 특정 작업이 있습니다 List::of
와는 Arrays::asList
차이가 :
+----------------------+---------------+----------+----------------+---------------------+
| 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 | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
- ✔️ 방법이 지원됨을 의미합니다.
- ❌는이 메서드를 호출하면 UnsupportedOperationException이 발생 함을 의미합니다.
- ❗️는 메서드의 인수가 변이를 일으키지 않는 경우에만 메서드가 지원됨을 의미합니다. 예를 들어 Collections.singletonList ( “foo”). retainAll ( “foo”)은 괜찮지 만 Collections.singletonList ( “foo”). retainAll ( “bar”) ) UnsupportedOperationException 발생
Collections :: singletonList Vs 에 대한 추가 정보 목록 ::의