JavaRush /Java Blog /Random-KO /Java의 지도에 관한 주요 9가지 질문
Treefeed
레벨 21

Java의 지도에 관한 주요 9가지 질문

Random-KO 그룹에 게시되었습니다
맵은 일련의 키-값 쌍으로 구성된 구조화된 데이터이며 각 키는 단일 맵에서 한 번만 사용할 수 있다는 점을 기억하세요 . 이 항목에서는 Java 및 구현된 클래스에서 Map 사용에 대한 9가지 기본 질문을 다룹니다. 단순화를 위해 예제에서는 일반화를 사용하겠습니다 . 따라서 Map 지정자를 지정하지 않고 간단하게 Map을 작성하겠습니다. 그러나 KV 의 값이 모두 비슷하다고 가정할 수 있습니다 . 이는 K가 Comparable을 확장 하고 VComparable을 확장한다는 의미입니다 .Java의 지도에 관한 상위 9가지 질문 - 1

0. 지도를 목록으로 변환하기

Java에서 Map 인터페이스 는 키 세트, 값 세트, 키-값 세트라는 세 가지 종류의 컬렉션을 제공합니다. 이들 모두는 생성자나 메소드를 사용하여 목록addAll() 으로 바뀔 수 있습니다 . 다음 코드 조각은 지도에서 ArrayList를 만드는 방법을 보여줍니다.
// list of keys
List keyList = new ArrayList(Map.keySet());
//list of values
List valueList = new ArrayList(Map.valueSet());
//list key-value
List entryList = new ArrayList(Map.entrySet());

1. 맵의 모든 값을 반복합니다.

각 키-값 쌍을 살펴보는 것은 맵을 살펴보는 가장 기본적인 절차입니다. Java에서 각 쌍은 Map.Entry 라는 Map 필드에 저장됩니다 . Map.entrySet()키-값 세트를 반환하므로 Map의 모든 값을 반복하는 가장 효율적인 방법은 다음과 같습니다.
for(Entry entry: Map.entrySet()) {
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}
Iterator특히 JDK 1.5보다 낮은 버전에서는 을 사용할 수도 있습니다.
Iterator itr = Map.entrySet().iterator();
while(itr.hasNext()) {
  Entry entry = itr.next();
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}

2. 키별 지도 주문

키로 지도를 구성하는 것은 일반적으로 사용되는 또 다른 절차입니다. 첫 번째 방법은 목록에 Map.Entry를 추가하고 값별로 정렬하는 비교기를 사용하여 정렬하는 것입니다.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getKey().compareTo(e2.getKey());
  }
});
또 다른 방법: 키를 순서대로 정렬하는 SortedMap 을 사용하는 것입니다. 그러나 모든 키는 Comparable을 구현하거나 비교기에서 허용되어야 합니다. 구현된 클래스 중 하나는 TreeMapSortedMap 입니다 . 생성자는 비교기를 허용합니다. 다음 코드는 일반 코드를 정렬된 코드로 바꾸는 방법을 보여줍니다. Map
SortedMap sortedMap = new TreeMap(new Comparator() {

  @Override
  public int compare(K k1, K k2) {
    return k1.compareTo(k2);
  }

});
sortedMap.putAll(Map);

3. 값별 주문 맵

이 경우에는 목록에 지도를 추가한 다음 정렬하는 것이 작동하지만 이번에는 를 사용해야 합니다 Entry.getValue(). 아래 코드는 이전과 거의 동일합니다.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getValue().compareTo(e2.getValue());
  }

});
이 경우에도 사용할 수 SortedMap있지만 값이 고유한 경우에만 사용할 수 있습니다. 이 경우 키-값 쌍을 키-값으로 바꿀 수 있습니다. 이 솔루션에는 심각한 제한이 있으므로 권장하지 않습니다.

4. 정적/불변 지도 초기화

지도를 변경 불가능한 상태로 유지하려는 경우 지도를 변경 불가능한 지도에 복사하는 것이 좋은 방법입니다. 이 방어 프로그래밍 기술은 사용하기에 안전할 뿐만 아니라 스레드에도 안전한 맵을 만드는 데 도움이 됩니다. 정적/불변 맵을 초기화하려면 초기화 프로그램을 사용할 수 있습니다 static(아래 참조). 이 코드의 문제점은 Map을 으로 선언했음에도 불구하고 static final초기화 후에도 계속 작업할 수 있다는 것입니다(예: ) Test.Map.put(3,"three");. 따라서 이는 실제 불변성이 아닙니다. 정적 초기화 프로그램을 사용하여 불변 지도를 생성하려면, 마지막 초기화 단계에서 불변 지도에 추가할 슈퍼 익명 클래스가 필요합니다. 코드의 두 번째 부분을 살펴보시기 바랍니다. 을 실행하면 UnsupportedOperationException이 발생하는 경우 Test.Map.put(3,"three");.
public class Test {

  private static final Map Map;
  static {
    Map = new HashMap();
    Map.put(1, "one");
    Map.put(2, "two");
  }
}
public class Test {

  private static final Map Map;
  static {
    Map aMap = new HashMap();
    aMap.put(1, "one");
    aMap.put(2, "two");
    Map = Collections.unmodifiableMap(aMap);
  }
}
Guava 라이브러리는 정적 및 불변 컬렉션을 초기화하는 다양한 방법도 지원합니다. Guava의 불변 컬렉션 유틸리티의 이점에 대해 자세히 알아보려면 Guava How-to의 Immutable Collections 섹션을 참조하세요 .

5. HashMap, TreeMap, Hashtable의 차이점

Java에는 Map 인터페이스 의 세 가지 주요 구현이 있습니다 : HashMap , TreeMapHashtable . 주요 차이점은 다음과 같습니다.
  • 통과순서 . HashMap 과 HashTable은 맵의 순서를 보장하지 않습니다. 특히 시간이 지나도 주문이 동일하게 유지된다는 보장은 없습니다. 그러나 TreeMap키의 "자연 순서"나 비교기에 따라 모든 값을 정렬합니다.
  • 유효한 키-값 쌍. HashMap널 키와 널 값을 가질 수 있습니다. HashTablenull 키 또는 null 값을 허용하지 않습니다. 자연 순서가 사용 되거나 TreeMap비교기가 널 키를 허용하지 않으면 예외가 발생합니다.
  • 동기화 . 동기화 만 HashTable되고 나머지는 동기화되지 않습니다. 그러나 "스레드 안전 구현이 필요하지 않은 경우 "를 HashMap대신 사용하는 것이 좋습니다 HashTable.
좀 더 자세한 비교
.                       | HashMap | HashTable | TreeMap
-------------------------------------------------------

Упорядочивание          |нет      |нет        | да
null в ключ-meaning    | да-да   | нет-нет   | нет-да
синхронизировано        | нет     | да        | нет
производительность      | O(1)    | O(1)      | O(log n)
воплощение              | корзины | корзины   | красно-чёрное дерево
HashMap과 관계 에 대해 자세히 알아보세요 . 트리맵 대 해시테이블과 해시테이블 비교 LinkedHashMap .

6. 역방향 검색/보기가 가능한 지도

때로는 키-키 쌍 세트가 필요합니다. 이는 값이 키만큼 고유하다는 것을 의미합니다(일대일 패턴). 이러한 일관성을 통해 지도에서 "역전된 보기/검색"을 만들 수 있습니다. 즉, 값으로 키를 찾을 수 있습니다. 이 데이터 구조를 양방향 Map 이라고 부르는데 , 불행하게도 JDK에서는 지원되지 않습니다. Apache Common Collections와 Guava는 각각 BidiMap 및 BiMap이라는 양방향 맵 구현을 제공합니다. 둘 다 키와 값 사이의 1:1 매핑을 강제하는 제약 조건을 도입합니다.

7. 지도의 얕은 사본

전부는 아니더라도 거의 모든 Java 맵에는 다른 맵에 대한 복사 생성자가 포함되어 있습니다. 그러나 복사 절차가 동기화되지 않습니다. 이는 한 스레드가 Map을 복사하면 다른 스레드가 해당 구조를 변경할 수 있음을 의미합니다. 갑작스러운 복사 비동기화를 방지하려면 이러한 경우에 둘 중 하나를 사용해야 합니다 Collections.synchronizedMap().
Map copiedMap = Collections.synchronizedMap(Map);
얕게 복사하는 또 다른 흥미로운 방법은 clone(). 그러나 Java 컬렉션 프레임워크의 창시자인 Joshua Bloch도 권장하지 않습니다. " 복사 생성자 대 복제 " 논쟁에서 그는 다음과 같은 입장을 취합니다. 인용: "사람들이 거기에 있을 것이라고 기대하기 때문에 나는 종종 공개 복제 메소드를 구체적인 클래스에 포함합니다. ... 복제가 중단된 것은 유감스러운 일입니다. 복제는 약점이고, 사람들에게 그 한계에 대해 경고해야 한다고 생각합니다." clone()그렇기 때문에 지도를 복사하는 방법도 보여주지 않습니다.

8. 빈 지도 만들기

변경할 수 없는 경우 Map다음을 사용하세요.
Map = Collections.emptyMap();
또는 다른 구현을 사용하십시오. 예를 들어:
Map = new HashMap();
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION