배열에서 변경 가능한 목록을 만드시겠습니까?


84

배열 List의 내용을 수정하기 위해으로 바꾸고 싶은 배열이 있습니다.

스택 오버플로는 주소가 있다는 질문 / 답변을 많이 가지고 Arrays.asList()그리고 그것은 단지 기본으로되는 배열의 목록보기를 제공하는 방법, 어떻게 결과 목록을 조작하려고 시도하는 것은 일반적으로 발생합니다 UnsupportedOperationException(예를 들어, 목록을 조작하기 위해 사용되는 방법으로 add(), remove()등)됩니다 에서 제공하는 List 구현에 의해 구현되지 않았습니다 Arrays.asList().

그러나 배열을 변경 가능한 목록으로 바꾸는 방법에 대한 예를 찾을 수 없습니다. 배열과 put()각 값을 새 목록으로 반복 할 수 있다고 가정 하지만이를 위해 존재하는 인터페이스가 있는지 궁금합니다.

답변:


122

한 가지 간단한 방법 :

Foo[] array = ...;
List<Foo> list = new ArrayList<Foo>(Arrays.asList(array));

그러면 변경 가능한 목록이 생성되지만 원래 배열 의 복사본 이됩니다. 목록을 변경해도 배열 은 변경 되지 않습니다 . 물론 나중에를 사용하여 다시 복사 할 수 있습니다 toArray.

배열에 변경 가능한 를 생성 하려면 직접 구현해야한다고 생각합니다.


2
Arrays.asList 목록의 크기에 영향을주지 않는 지원하는 돌연변이 방법과 배열에 뷰를 돌려줍니다
티모 Westkämper에게

1
@ jon-skeet 내가 아는, Arrays.asList가 제한된 가변성을 가진 배열 지원 목록을 제공한다고 말하고 있었는데 추가 / 제거 / 삽입이 필요한 경우 ArrayList 래핑이 더 나은 방법입니다.
Timo Westkämper

4
자바는 이러한 모든 정적 팩토리 메소드에서 변경 / 불변성을 명확히해야합니다. 당신이 런타임에 불변의 것을 만들었다는 사실을 알게 된 것은 안타까운 일입니다.
dustinevan

1
@dustinevan : 문서는 매우 명확합니다. IMO : "지정된 배열에 의해 지원되는 고정 크기 목록을 반환합니다. (반환 된 목록을 배열에"쓰기 "로 변경합니다.)"
Jon Skeet

1
@JonSkeet는 시간을 낭비하고 싶지 않습니다. 모든 일에 감사드립니다. 이름 자체를 더 명확하게하기 위해 투표를하고 싶습니다. 문서가 명확하다고 확신합니다. 우리 중 일부는 언어 사이에서 춤을 추고 있으며 이것은 다른 언어에서 합리적으로 명확합니다.
dustinevan

21

그리고 Google 컬렉션 API를 사용하는 경우

Lists.newArrayList(myArray)

1
이것이 가장 간결한 대답입니다. 감사.
eugene82

2
Guava 자체도 둘 중 하나를 사용하도록 권장 new ArrayList<>(Arrays.asList(...))합니다. 메소드에 대한 javadoc은 유용하지 않기 때문에 더 이상 사용되지 않을 것임을 의미합니다.
Logan Pickup

2020 년이며 여전히 더 이상 사용되지 않습니다. 뛰어!
markthegrea

11

Java 8에 포함 된 Stream API를 사용하는이 간단한 코드는 배열의 요소를 포함하는 변경 가능한 목록 (또는보기)을 만듭니다.

Foo[] array = ...;
List<Foo> list = Stream.of(array).collect(Collectors.toCollection(ArrayList::new));

또는 동일하게 유효합니다.

List<Foo> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));

4

당신이 사용하는 경우 이클립스 컬렉션 (구 GS 컬렉션 ), 당신은 사용할 수 있습니다 FastList.newListWith(...)또는 FastList.wrapCopy(...).

두 방법 모두 varargs를 사용하므로 배열을 인라인으로 만들거나 기존 배열을 전달할 수 있습니다.

MutableList<Integer> list1 = FastList.newListWith(1, 2, 3, 4);

Integer[] array2 = {1, 2, 3, 4};
MutableList<Integer> list2 = FastList.newListWith(array2);

두 방법의 차이점은 배열이 복사되는지 여부입니다. newListWith()배열을 복사하지 않으므로 일정한 시간이 걸립니다. 배열이 다른 곳에서 변경 될 수 있다는 것을 알고 있다면 사용하지 않아야합니다.

Integer[] array2 = {1, 2, 3, 4};
MutableList<Integer> list2 = FastList.newListWith(array2);
array2[1] = 5;
Assert.assertEquals(FastList.newListWith(1, 5, 3, 4), list2);

Integer[] array3 = {1, 2, 3, 4};
MutableList<Integer> list3 = FastList.wrapCopy(array3);
array3[1] = 5;
Assert.assertEquals(FastList.newListWith(1, 2, 3, 4), list3);

참고 : 저는 Eclipse Collections의 커미터입니다.


1
그것은 당신이 가지고있는 멋진 컬렉션 API입니다. 내 자신의 구현에서 나를 유혹 할 수있는 첫 번째는 ... 일반적으로 유용하다고 생각되는 유일한 것은 배열로 뒷받침되는 정렬 된 집합 구현입니다. 거의 수정되지 않는 데이터 또는 자주 수정 될 수 있지만 일반적으로 10 개 미만의 요소를 보유하는 집합에 대한 트리 기반 구현).
Jules

0
myNewArrayList = new ArrayList<>(Arrays.asList(myArray));

1
@JonSkeet 저는 귀하의 의견이 2012 년의 것임을 알고 있으며 저는 현재 미래에 살고 있습니다.하지만이 의견이 제 IDE에 구체적으로 밑줄을 긋고 "어이, 이것을 선언하지 마세요. 선언 된 유형입니다. 필요하지 않습니다. "?
브렌트 Thoenen

1
@BrentThoenen : 귀하의 의견을 이해할 수 없습니다. 내 의견이 myNewArrayList = new ArrayList(...), 즉 원시 유형 을 사용하는 개정 1을 참조한다는 것을 알았습니까 ? "컴파일러가 형식 인수를 처리하도록 다이아몬드 연산자를 사용하는 것"과 "원시 형식을 사용하는 것"에는 차이가 있습니다.
Jon Skeet

1
나는이 대답을 게시하고 @JonSkeet 자신이 내 대답에 대해 언급 한 모든 시간을 망각 속에 살았습니다. 의견을 보내 주신 Brent에게 감사드립니다.
Sid

@JonSkeet 아, 내 나쁜. 나는 당신이 주석을다는 개정판을 확인하지 않았습니다. 2012 자바가 빈 다이아몬드 연산자를 원시 유형으로 간주한다는 잘못된 가정을했습니다. 그것은 나의 b입니다. 답변 해주셔서 감사합니다!
Brent Thoenen 19.07.25

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.