한 줄로 Java 목록 초기화

1. 소개

이 빠른 자습서에서는 한 줄을 사용하여 List 를 초기화하는 방법을 조사합니다 .

2. 어레이에서 생성

배열에서 List 를 만들 수 있으며 배열 리터럴 덕분에 한 줄로 초기화 할 수 있습니다.

List list = Arrays.asList(new String[]{"foo", "bar"});

배열 생성을 처리하기 위해 varargs 메커니즘을 신뢰할 수 있습니다. 이를 통해 더 간결하고 읽기 쉬운 코드를 작성할 수 있습니다.

@Test public void givenArraysAsList_thenInitialiseList() { List list = Arrays.asList("foo", "bar"); assertTrue(list.contains("foo")); }

이 코드의 결과 인스턴스는 List 인터페이스를 구현 하지만 java.util.ArrayListLinkedList 도 아닙니다 . 대신 두 가지 의미가있는 원래 배열이 지원 하는 목록 입니다.

그러나 클래스의 이름은 ArrayList 이지만 java.util.Arrays 패키지에 있습니다.

2.1. 고정 크기

Arrays.asList 의 결과 인스턴스 는 고정 된 크기를 갖습니다.

@Test(expected = UnsupportedOperationException.class) public void givenArraysAsList_whenAdd_thenUnsupportedException() { List list = Arrays.asList("foo", "bar"); list.add("baz"); }

2.2. 공유 참조

원래 배열과 목록은 객체에 대한 동일한 참조를 공유합니다.

@Test public void givenArraysAsList_whenCreated_thenShareReference(){ String[] array = {"foo", "bar"}; List list = Arrays.asList(array); array[0] = "baz"; assertEquals("baz", list.get(0)); }

3. 스트림에서 생성 (Java 8)

Stream 을 모든 종류의 컬렉션 으로 쉽게 변환 할 수 있습니다 .

따라서 Streams 의 팩토리 메서드를 사용하여 한 줄로 목록을 만들고 초기화 할 수 있습니다.

@Test public void givenStream_thenInitializeList(){ List list = Stream.of("foo", "bar") .collect(Collectors.toList()); assertTrue(list.contains("foo")); }

Collectors.toList () 가 반환 된 List 의 정확한 구현을 보장하지 않는다는 것을 여기에 표시해야합니다 .

반환 된 인스턴스의 변경 가능성, 직렬화 가능성 또는 스레드 안전성에 대한 일반적인 계약은 없습니다. 따라서 우리 코드는 이러한 속성에 의존해서는 안됩니다.

일부 소스에서는 Stream.of (…) .collect (…)Arrays.asList () 보다 더 큰 메모리와 성능 공간을 가질 수 있다고 강조 하지만 거의 모든 경우에 차이가 거의없는 마이크로 최적화입니다.

4. 팩토리 메소드 (Java 9)

JDK 9에서는 컬렉션에 대해 몇 가지 편리한 팩토리 메서드가 도입되었습니다.

List list = List.of("foo", "bar", "baz"); Set set = Set.of("foo", "bar", "baz");

한 가지 중요한 세부 사항은 반환 된 인스턴스가 변경 불가능하다는 것 입니다. 그 외에도 팩토리 방법은 공간 효율성과 스레드 안전성에서 몇 가지 장점이 있습니다.

이 주제는이 기사에서 자세히 살펴 봅니다.

5. 이중 중괄호 초기화

여러 곳에서 다음과 같은 '이중 중괄호 초기화' 라는 메서드를 찾을 수 있습니다 .

@Test public void givenAnonymousInnerClass_thenInitialiseList() { List cities = new ArrayList() {{ add("New York"); add("Rio"); add("Tokyo"); }}; assertTrue(cities.contains("New York")); }

'이중 중괄호 초기화' 라는 이름 은 오해의 소지가 있습니다. 구문은 간결하고 우아하게 보일 수 있지만 내부에서 일어나는 일을 위험하게 숨 깁니다.

Java 에는 실제로 '이중 중괄호' 구문 요소 가 없습니다. 이 두 블록은 의도적으로 이런 방식으로 형식화되었습니다.

외부 중괄호를 사용하여 ArrayList 의 하위 클래스가 될 익명 내부 클래스를 선언합니다 . 이 중괄호 안에 서브 클래스의 세부 사항을 선언 할 수 있습니다.

평소와 같이 인스턴스 이니셜 라이저 블록을 사용할 수 있으며 여기에서 내부 중괄호 쌍이 생성됩니다.

이 구문의 간결함은 유혹적이지만 반 패턴으로 간주됩니다.

이중 중괄호 초기화에 대해 자세히 알아 보려면 여기에서 기사를 참조하십시오.

6. 결론

Modern Java는 컬렉션 을 한 줄로 생성하는 여러 옵션을 제공합니다 . 우리가 선택한 방법은 기술적 인 추론보다는 거의 전적으로 개인적인 선호에 달려 있습니다.

중요한 점은 우아해 보이지만 익명의 내부 클래스 초기화 (일명 '이중 중괄호')의 안티 패턴에는 많은 부정적인 부작용이 있다는 것 입니다.

항상 그렇듯이 코드는 GitHub에서 사용할 수 있습니다.