[java] Collections.emptyMap () 대 새로운 HashMap ()

내가 사용할 수있는 상황은 무엇입니까 Collections.emptyMap()? 문서에 컬렉션을 변경할 수 없게하려면이 방법을 사용할 수 있다고 나와 있습니다.

변경 불가능한 빈 컬렉션을 원하는 이유는 무엇입니까? 요점이 뭐야?



답변

에서 효과적인 자바 , 항목 # 43"Return empty arrays or collections, not null"빈 컬렉션을 반환하는 방법을 보여줍니다 그리고 어쩌면이 사용하는 방법을 보여줍니다 emptyList(), emptySet()그리고 emptyMap()또한 불변의 존재의 추가 혜택을 가지고 하늘의 콜렉션을 얻을 수있는 컬렉션 클래스의 메소드를. 에서 항목 # 15 "Minimize Mutability" .

에서 컬렉션 – emptySet – 컬렉션 – 빈리스트 – 컬렉션

프로그래밍 관용구의 유형입니다. 이것은 널 변수를 원하지 않는 사람들을위한 것입니다. 따라서 세트가 초기화되기 전에 빈 세트를 사용할 수 있습니다.

참고 : 아래 코드는 예제 일뿐입니다 (사용 사례에 따라 변경).

private Set myset = Collections.emptySet();

void initSet() {
   myset = new HashSet();
}
void deleteSet() {
   myset = Collections.emptySet();
}

이러한 방법은 몇 가지 장점을 제공합니다.

  1. 컬렉션의 제네릭 형식을 명시 적으로 입력 할 필요가 없기 때문에 더 간결합니다. 일반적으로 메서드 호출 컨텍스트에서 유추됩니다.

  2. 새로운 객체 생성을 방해하지 않기 때문에 더 효율적입니다. 기존의 비어 있고 불변 인 객체를 재사용합니다. 이 효과는 일반적으로 매우 작지만 때때로 (잘 드물게) 중요합니다.


답변

필자의 개인적 경험에 따르면 API에 매개 변수 모음이 필요하지만 제공 할 것이없는 경우에 매우 유용합니다. 예를 들어 다음과 같은 API를 가지고 null 참조를 허용하지 않을 수 있습니다.

public ResultSet executeQuery(String query, Map<String, Object> queryParameters);

매개 변수를 사용하지 않는 쿼리가있는 경우 실제로 상수 인 ‘빈지도’를 전달할 수있을 때 배열 할당과 관련된 HashMap을 만드는 것은 약간 낭비입니다. 에서 java.util.Collections.


답변

변경 불가능한 빈 컬렉션을 원하는 이유는 무엇입니까? 요점이 뭐야?

함께 볼 때 이상하게 보이는 두 가지 다른 개념이 있습니다. 두 개념을 개별적으로 취급 할 때 더 의미가 있습니다.

  • 먼저, 가능한 한 변경 불가능한 콜렉션 대신 변경 불가능한 콜렉션을 사용하는 것이 좋습니다. 불변의 이점은 다른 곳에기록되어 있습니다 .

  • 둘째, null을 센티넬로 사용하는 대신 빈 컬렉션을 사용하는 것이 좋습니다. 여기에 잘 설명되어 있습니다 . 즉, 버그를 숨길 수있는 장소가 적어 훨씬 더 깨끗하고 이해하기 쉬운 코드를 갖게됩니다.

따라서 맵이 필요한 코드가 있으면 맵이 없음을 나타 내기 위해 null 대신 빈 맵을 전달하는 것이 좋습니다. 그리고 대부분의 경우 맵을 사용하는 경우 불변의 맵을 사용하는 것이 좋습니다. 따라서 불변의 빈 맵을 만드는 편리한 기능이 있습니다.


답변

변경 불가능한 맵, 목록, 세트 또는 기타 유형의 콜렉션을 선호하는 경우가 몇 가지 있습니다.

먼저 당신이 쿼리 나 결과의 집합 (또는 목록이나지도를) 반환 계산의 결과를 반환 할 때마다 틀림없이 가장 중요한 유스 케이스는, 당신은 불변의 데이터 구조를 사용하는 것을 선호한다.

이 경우 불변 버전을 반환하는 것이 좋습니다.이 결과는 계산 결과 집합의 사실 불변성을 훨씬 더 명확하게 반영합니다. 나중에 데이터로 무엇을하든 쿼리에서받은 결과 집합은 그렇지 않아야합니다. 변화.

두 번째 일반적인 유스 케이스는 메소드 또는 서비스의 입력으로 인수를 제공해야하는 경우입니다. 입력 콜렉션이 서비스 또는 메소드 (일반적으로 실제로는 나쁜 설계 아이디어)에 의해 수정 될 것으로 예상 하지 않는 한 , 가변 콜렉션 대신 불변 콜렉션을 전달하는 것이 많은 경우 합리적이고 안전한 선택이 될 수 있습니다.

나는 그것을 “가치가 지나가는” 관습 이라고 생각합니다 .

보다 일반적으로 -데이터가 모듈 또는 서비스 경계를 ​​넘을 때마다 불변의 데이터 구조를 사용하는 것이 현명합니다. 이것은 (불변) 입력 / 출력과 변하기 쉬운 내부 상태 사이의 차이점을 훨씬 쉽게 추론 할 수있게합니다.

이로 인한 부작용으로 모듈 / 서비스의 보안 및 스레드 안전성이 향상되고 문제를보다 명확하게 분리 할 수 ​​있습니다.

Collections.empty*()방법 을 사용 하는 또 다른 좋은 이유 는 눈에 띄는 자세한 정보 부족 때문입니다. Java7 이전 시대에는 제네릭 컬렉션이있는 경우 모든 곳에서 제네릭 형식 주석을 뿌려야했습니다.

이 두 선언을 비교하십시오.

Map<Foo, Comparable<? extends Bar>> fooBarMap = new HashMap<Foo, Comparable<? extends Bar>>();

대:

Map<Foo, Comparable<? extends Bar>> fooBarMap = Collections.emptyMap();

후자는 다음과 같은 두 가지 중요한 방법으로 가독성에 대한 확실한 결론을 얻습니다.

  1. 첫 번째 선언에서 빈 맵의 전체 인스턴스화는 일반 유형 선언의 소음에 묻혀 본질적으로 사소한 선언이 필요한 것보다 훨씬 더 복잡합니다.
  2. 오른쪽에 일반적인 유형 주석이 눈에 띄지 않고 두 번째 버전에서는 맵이 빈 맵으로 초기화되었다고 명확하게 설명합니다. 또한이 방법이 불변의 맵을 반환한다는 것을 알면 이제 검색만으로 비어 있지 않은fooBarMap 다른 값 이 할당 된 위치를 쉽게 찾을 수 있습니다./fooBarMap =/

답변

하나는 참조 공유를 통해 얻을 수 있습니다. new HashMap()등은 할당 된 개체가 필요합니다, 그리고 아마도 몇 가지 추가 요소는 데이터를 보유하지만, 당신은 단지 하나의 불변의 빈 콜렉션 (목록, 설정,지도, 또는 기타 등)로 복사해야합니다. 호출하는 메소드가 맵을 승인해야하지만 편집 할 필요가없는 경우에는이를 명백히 선택합니다.

Josh Bloch의 Effective Java를 확인하여 불변의 객체 (스레드 안전성 포함)의 매우 훌륭한 속성을 나열하는 것이 좋습니다.


답변

반환하는 함수가 immutable collection있고 어떤 상황에서 반환 할 데이터가 없으므로 반환하는 대신 반환 null할 수 있으면 유용 할 수 있습니다emptyMap()

코드를 더 쉽게 만들고 방지합니다. NullPointerException


답변

대부분의 경우 a constructor를 사용하여 새을 만듭니다 empty map. 그러나 Collections methods장점을 제공 서너은 만들 수 empty map사용을static method java.util.Collections.emptyMap()

  1. 컬렉션의 제네릭 형식을 명시 적으로 입력 할 필요가 없기 때문에 더 간결합니다. 일반적으로 메서드 호출 컨텍스트에서 유추됩니다.

  2. 새로운 객체 생성을 방해하지 않기 때문에 더 효율적입니다. 기존의 비어 있고 불변 인 객체를 재사용합니다. 이 효과는 일반적으로 매우 작지만 때때로 (잘 드물게) 중요합니다.