[java] 한 줄로 ArrayList 초기화

테스트 목적으로 옵션 목록을 만들고 싶었습니다. 처음에 나는 이것을했다 :

ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");

그런 다음 코드를 다음과 같이 리팩터링했습니다.

ArrayList<String> places = new ArrayList<String>(
    Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

더 좋은 방법이 있습니까?



답변

실제로, 아마도 초기화하는 가장 좋은 ArrayList방법은 여러분이 작성한 방법 일 것입니다. 왜냐하면 List어떤 식 으로든 새로운 것을 만들 필요가 없기 때문입니다 .

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");

잡는 것은 그 list인스턴스 를 참조하기 위해 약간의 타이핑이 필요하다는 것 입니다.

인스턴스 이니셜 라이저 ( “중괄호 초기화”라고도 함)를 사용하여 익명의 내부 클래스를 만드는 것과 같은 대안이 있습니다.

ArrayList<String> list = new ArrayList<String>() {{
    add("A");
    add("B");
    add("C");
}};

그러나, 당신이 끝내는 ArrayList것은 인스턴스 이니셜 라이저 가있는 서브 클래스이며 , 그 클래스는 하나의 객체를 만들기 위해 만들어 지기 때문에 그 방법을 좋아하지 않습니다 .

좋은 점은 Project Coin 에 대한 Collection Literals 제안 이 수락 된 경우였습니다 (Java 7에서 도입 될 예정이지만 Java 8에도 포함되지는 않습니다).

List<String> list = ["A", "B", "C"];

불행히도 여기 List보다는 불변을 초기화 할 것이므로 여기에서는 도움이되지 않으며 ArrayList, 더 이상 사용할 수 없다면 아직 사용할 수 없습니다.


답변

그냥 선언하면 List– 더 간단 합니다-ArrayList 여야합니까?

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

또는 하나의 요소 만있는 경우 :

List<String> places = Collections.singletonList("Buenos Aires");

이것은 그 의미 places한다 불변 (그것이 원인이됩니다 변경하려고 UnsupportedOperationException예외가 슬로우).

구체적으로 변경 가능한 목록을 만들려면 변경할 ArrayListArrayList없는 목록에서 만들 수 있습니다 .

ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));


답변

간단한 대답

에서 자바 9 이상, 이후에 List.of()추가되었습니다

List<String> strings = List.of("foo", "bar", "baz");

함께 자바 10 이상 또는,이은으로 단축 할 수 있습니다 var키워드.

var strings = List.of("foo", "bar", "baz");

이것은 당신에게 불변 을 줄 List것이므로 변경할 수 없습니다.
당신이 그것을 미리 채우는 대부분의 경우에 당신이 원하는 것입니다.


Java 8 이하 :

List<String> strings = Arrays.asList("foo", "bar", "baz");

이렇게하면 List배열 이 지원되므로 길이를 변경할 수 없습니다.
그러나 당신은 호출 할 수 List.set있으므로 여전히 변경 가능 합니다.


Arrays.asList정적 가져 오기로 더 짧게 만들 수 있습니다 .

List<String> strings = asList("foo", "bar", "baz");

정적 가져 오기 :

import static java.util.Arrays.asList;  

최신 IDE가 자동으로 제안하고 자동으로 수행합니다.
예를 들어 IntelliJ IDEA에서을 누르고을 Alt+Enter선택 Static import method...합니다.


그러나 혼동을 일으키기 때문에 List.of방법을 단축하는 것은 좋지 않습니다 of.
List.of이미 충분히 짧고 잘 읽습니다.


Streams 사용

왜 그래야 List합니까?
Java 8 이상 Stream에서는 더 유연한 것을 사용할 수 있습니다 .

Stream<String> strings = Stream.of("foo", "bar", "baz");

Streams 를 연결할 수 있습니다 .

Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
                                       Stream.of("baz", "qux"));

또는 a에서 a Stream로 이동할 수 있습니다 List.

import static java.util.stream.Collectors.toList;

List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());

그러나 가급적이면로 Stream수집하지 않고 사용하십시오 List.


당신이 경우 정말 특별히 필요java.util.ArrayList

(당신은 아마하지 않습니다.)
인용하자면 JEP 269 (강조 광산) :

작은 설정 값을 미리 정의 된 집합으로 변경 가능한 콜렉션 인스턴스를 초기화 사용 사례는. 일반적으로 사전 정의 된 값을 변경할 수없는 콜렉션에두고 복사 생성자를 통해 변경 가능한 콜렉션을 초기화하는 것이 좋습니다.


당신이 원하는 경우 모두 미리 채울 ArrayList (왜?) 이후에 그것을 사용을 추가

ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");

또는 Java 8 이하에서 :

ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");

또는 사용 Stream:

import static java.util.stream.Collectors.toCollection;

ArrayList<String> strings = Stream.of("foo", "bar")
                             .collect(toCollection(ArrayList::new));
strings.add("baz");

그러나 다시 Stream로 수집하는 대신 직접 사용하는 것이 좋습니다 List.


구현이 아닌 인터페이스에 대한 프로그램

ArrayList코드에서 목록을로 선언했다고 말 했지만에 ArrayList없는 일부 멤버를 사용하는 경우에만 목록을 작성해야합니다 List.

당신이하지 않을 가능성이 가장 높습니다.

일반적으로 당신은 당신이 (예를 들어, 사용하려고하는 가장 일반적인 인터페이스 변수를 선언해야한다 Iterable, Collection또는 List), 및 특정의 구현을 초기화 (예를 들어 ArrayList, LinkedList또는 Arrays.asList()).

그렇지 않으면 코드를 특정 유형으로 제한하므로 원하는 때 변경하기가 더 어려워집니다.

예를 들어, ArrayList에 a를 전달하는 경우 void method(...):

// Iterable if you just need iteration, for (String s : strings):
void method(Iterable<String> strings) {
    for (String s : strings) { ... }
}

// Collection if you also need .size(), .isEmpty(), or .stream():
void method(Collection<String> strings) {
    if (!strings.isEmpty()) { strings.stream()... }
}

// List if you also need .get(index):
void method(List<String> strings) {
    strings.get(...)
}

// Don't declare a specific list implementation
// unless you're sure you need it:
void method(ArrayList<String> strings) {
    ??? // You don't want to limit yourself to just ArrayList
}

또 다른 예 InputStream는 보통 a FileInputStream또는 a 이지만 변수를 항상 선언하는 것입니다. BufferedInputStream언젠가 당신이나 다른 누군가가 다른 종류의를 사용하기를 원하기 때문입니다 InputStream.


답변

간단한 크기 목록 1이 필요한 경우 :

List<String> strings = new ArrayList<String>(Collections.singletonList("A"));

여러 객체의 목록이 필요한 경우 :

List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");


답변

구아바 를 사용하면 다음과 같이 작성할 수 있습니다.

ArrayList<String> places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata");

구아바에는 또 다른 유용한 정적 생성자가 있습니다. 여기에서 그들에 대해 읽을 수 있습니다 .


답변

컬렉션 리터럴은 Java 8로 만들지 않았지만 Stream API를 사용하여 하나의 긴 줄로 목록을 초기화 할 수 있습니다.

List<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toList());

당신은 당신이 있는지 확인해야하는 경우 List입니다 ArrayList:

ArrayList<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new));


답변

JEP 269 : Convenience Factory Methods for Collections 에서 제안한 바와 같이, 이제는-를 사용하여 콜렉션 리터럴을 사용하여 달성 할 수 있습니다.

List<String> list = List.of("A", "B", "C");

Set<String> set = Set.of("A", "B", "C");

유사한 접근 방식에 적용되는 것 Map뿐만 아니라 –

Map<String, String> map = Map.of("k1", "v1", "k2", "v2", "k3", "v3")

이는 @coobird가 명시한 Collection Literals 제안 과 유사합니다 . JEP에서 더 명확히-


대안

언어 변경이 여러 번 고려되어 거부되었습니다.

프로젝트 코인 제안, 2009 년 3 월 29 일

프로젝트 코인 제안, 2009 년 3 월 30 일

2014 년 1 월 -3 월, lambda-dev에 대한 JEP 186 토론

언어 제안은이 메시지에 요약 된대로 라이브러리 기반 제안보다 우선적으로 제정되었습니다 .

관련 : Java 9에서 콜렉션에 대해 오버로드 된 편의 팩토리 메소드의 요점은 무엇입니까?