Arrays.asList () vs Collections.singletonList ()


137

Collections.singletonList (something)보다 Arrays.asList (something)를 사용하여 하나의 항목을 포함하는 목록을 만드는 것의 이점 (또는 많은 차이)이 있습니까? 후자는 반환 된 목록도 변경할 수 없습니다.


8
구아바 ImmutableList.of()Lists.newArrayList()믹스도 함께 던질 수 있습니다 .
biziclop

이 외에도, 메서드가 나중에 다운 스트림에서 수정 된 List를 반환 할 때 Collections.singletonList ()로 인해 문제가 발생했습니다.
Howard Grimberg

1
자바 (10)는 진정한 불변의리스트가 있습니다 stackoverflow.com/a/52536126/1216775
akhil_mittal

답변:


206

Collections.singletonList(something)불변 반면 Arrays.asList(something)고정 크기 인 List리스트와 어레이가 힙 접합 도착 어레이의 표현.

Arrays.asList(something)구조가 아닌 변경을 허용 하여 List 및 결합 된 배열 모두에 반영됩니다. 그것은 던졌습니다 UnsupportedOperationException특정 인덱스의 요소를 설정할 수 있지만 요소를 제거, 추가하는.

에 의해 반환 된 List에 대한 모든 변경 사항 Collections.singletonList(something)은 결과가됩니다 UnsupportedOperationException.

또한, 반환 된 List 의 용량은 백업 된 어레이의 용량 과 다른 용량 과 Collections.singletonList(something)항상 1Arrays.asList(something) 입니다.


63

나는 싱글 톤리스트가 배열에 의해 지원되지 않고 그 한 항목에 대한 참조 만 가지고 있다고 덧붙일 것입니다. 아마도 메모리를 덜 차지하고 만들려는 목록 수에 따라 중요 할 수 있습니다.


이 메모리 효율 포인트를 뒷받침하는 링크 또는 코드? 이 Arrays.asList (ONLY_ONE_OBJECT)를 코드베이스에 광범위하게 작성했으며 Collections.singletonList ()로 대체하면 메모리 효율성이 있는지 알고 싶습니다.
Rahul Saini


12

이 메서드 Arrays.asList는 지정된 배열을 기반으로하는 고정 크기 목록을 반환합니다. 상기 방법의 일 예를 리턴 ArrayListA는 어느 개인 중첩 정적 클래스 연장 AbstractList및하지 java.util.ArrayList. 이 정적 클래스는 예를 들어 몇 가지 메소드의 구현을 제공 set, indexOf, forEach, replaceAll하지만 호출 add할 때 자체 구현이 없으므로 from 메소드 AbstractList가 호출됩니다 java.lang.UnsupportedOperationException.

Collections.singletonList다시 표시 불변의리스트 지정된 오브젝트만을 포함하고 그것뿐만 아니라 직렬화 가능합니다.

참고로, 불변 목록의 경우 일반적으로 Collections.unmodifiableList지정된 목록의 수정 불가능한 뷰를 반환하는 것을 사용 합니다.

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

수정할 수없는보기 모음은 수정할 수없는 모음이며 배경 모음에 대한보기이기도합니다. 백업 컬렉션에 대한 변경은 여전히 ​​가능할 수 있으며, 변경이 발생하면 수정할 수없는보기를 통해 볼 수 있습니다.

우리는 Java 10 이상 에서 진정한 불변 목록을 가질 수 있습니다 . 진정한 수정 불가능한 목록 을 얻는 방법에는 두 가지가 있습니다 .

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); 이 두 변수 중 하나가 사용되면 값은 여전히 ​​"Apricot"가 아닌 "Apple"입니다.

Java 10 doc 에 따르면 :

List.ofList.copyOf정적 팩토리 메소드는 변경 불가능한 목록을 만들 수있는 편리한 방법을 제공합니다. 이 메소드로 작성된 List 인스턴스는 다음과 같은 특징이 있습니다.

  1. 그들은 수정할 수 없습니다 . 요소를 추가, 제거 또는 교체 할 수 없습니다. List에서 mutator 메소드를 호출하면 항상 발생 UnsupportedOperationException합니다. 그러나 포함 된 요소 자체가 변경 가능한 경우 목록의 내용이 변경 될 수 있습니다.
  2. 그들은 null 요소를 허용하지 않습니다. 널 요소를 사용하여 작성하려고하면 결과가 발생 NullPointerException합니다.
  3. 모든 요소가 직렬화 가능하면 직렬화 가능합니다.
  4. 목록의 요소 순서는 제공된 인수 또는 제공된 배열의 요소 순서와 같습니다.
  5. 그들은입니다 value-based. 호출자는 반환 된 인스턴스의 아이덴티티에 대해 가정해서는 안됩니다. 공장은 새로운 인스턴스를 생성하거나 기존 인스턴스를 재사용 할 수 있습니다. 따라서 이러한 인스턴스에서 ID에 민감한 작업 (참조 동등성 (==), ID 해시 코드 및 동기화)은 신뢰할 수 없으므로 피해야합니다.
  6. 이들은 직렬화 된 양식 페이지 에 지정된대로 직렬화됩니다 .
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.