Java 9는 목록에 대한 새로운 팩토리 메소드를 도입했습니다 List.of
.
List<String> strings = List.of("first", "second");
이전 옵션과 새 옵션의 차이점은 무엇입니까? 즉, 이것의 차이점은 무엇입니까?
Arrays.asList(1, 2, 3);
이:
List.of(1, 2, 3);
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]
List.contains(Object o)
의 javadoc의 "예외 [...] - 지정된 요소가 null이며,이리스트가 null 요소 (선택을) 허용하지 않을 경우". 또는 거의 읽지 않은 인터페이스의 긴 소개에서 "일부 컬렉션 구현에는 포함 할 수있는 요소에 대한 제한이 있습니다."
List.of
않는 일부 반환 ImmutableList
유형을, 실제 이름은 단지 비공개 구현 세부입니다. 공개되고 누군가가 List
다시 캐스팅했다면 차이점은 무엇입니까? 또는 시도 할 때 예외를 발생시키는 Arrays.asList
비공개 List
구현 을 반환하는 , 또는 수정이 전혀 허용되지 않는에서 반환 된 목록 의 차이점 은 무엇입니까? 인터페이스에 지정된 계약에 관한 것 입니다. 선택적 메소드가있는 Collections 인터페이스는 Java 1.2 이후 항상 불순한 OOP였습니다…add
remove
Collections.unmodifiableList
List
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
목록을 원할 때 와 변경할 수있는 목록을 원할 때 사용합니다 (위 그림 참조).
Arrays.asList
완전히 변경할 수 없습니다. asList.add(1);
던졌습니다 UnsupportedOperationException
.
List.of
사람들이 전화 contains
하고 싶어 하고 NullPointerException에 놀라지 않을 시간을 거의 사용할 수 없습니다 .
List.of 와 Arrays.asList 의 차이점을 요약 해 보겠습니다.
List.of
데이터 세트가 적고 변경되지 않은 Arrays.asList
경우 가장 잘 사용할 수있는 반면, 크고 동적 데이터 세트의 경우 가장 잘 사용할 수 있습니다.
List.of
필드 기반 구현이 있기 때문에 오버 헤드 공간을 매우 적게 차지하고 고정 오버 헤드와 요소 별 기준 모두에서 더 적은 힙 공간을 사용합니다. Arrays.asList
초기화하는 동안 힙에 더 많은 객체를 생성하기 때문에 더 많은 오버 헤드 공간 을 차지합니다.
에서 반환 된 컬렉션 List.of
은 변경 불가능하므로 스레드로부터 안전하지만에서 반환 된 컬렉션 Arrays.asList
은 변경 가능하며 스레드로부터 안전하지 않습니다. (불변 컬렉션 인스턴스는 일반적으로 가변 인스턴스보다 훨씬 적은 메모리를 사용합니다.)
List.of
허용하지 않는 널 동안 요소를 Arrays.asList
허용 널 (null) 요소를.
Arrays.asList
대 List.of
에 대해 이야기 할 때 사실이라는 것은 매우 회의적입니다 . 최소한 OpenJDK의 구현 은 매우 작은 오버 헤드를 가지고있는 것으로 보입니다. 실제로 List.of
전달 된 어레이의 복사본을 만들어야하므로 어레이 자체가 곧 GC가되지 않는 List.of
한 훨씬 더 큰 메모리 공간을 가진 것처럼 보일 것 입니다.
List.of(x)
그리고 List.of(x, y)
그들은 모두에 배열을 할당하지 않기 때문에 더 효율적
List.of
매번 새 목록을 반환하는 데 메서드가 필요 하지 않다는 것을 잊지 마십시오 . 이러한 목록에는 지정되지 않은 ID가 있으므로 JVM 수준에서 처리되는 캐싱 또는 중복 제거 또는 스칼라 화가있을 수 있습니다. 이 버전이 아니라면 아마도 다음 버전 일 것입니다. 계약에 의해 허용됩니다. 반대로 Array.asList
결과 목록은 배열에서 변경 가능한보기이므로 모든 변경 사항을 양방향으로 반영하므로 전달하는 배열의 ID에 따라 다릅니다.
외에도 위의 답변에서 두 가지 모두에 대해 특정 작업이 있습니다 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 | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
Collections :: singletonList Vs 에 대한 추가 정보 목록 ::의