테스트 목적으로 옵션 목록을 만들고 싶었습니다. 처음에 나는 이것을했다 :
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
예외가 슬로우).
구체적으로 변경 가능한 목록을 만들려면 변경할 ArrayList
수 ArrayList
없는 목록에서 만들 수 있습니다 .
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
이미 충분히 짧고 잘 읽습니다.
Stream
s 사용
왜 그래야 List
합니까?
Java 8 이상 Stream
에서는 더 유연한 것을 사용할 수 있습니다 .
Stream<String> strings = Stream.of("foo", "bar", "baz");
Stream
s 를 연결할 수 있습니다 .
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));
답변
와 자바 -9JEP 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에서 더 명확히-
대안
언어 변경이 여러 번 고려되어 거부되었습니다.