본문 바로가기
웹프로그래밍/Java

Java Maps

by Seras 2017. 11. 22.
반응형

일반적으로 Map 은 일련의 키 - 값 쌍 으로 구성된 데이터 구조 이며 각 키는지도에 한 번만 나타납니다. 이 글은 Java Map 과 구현 클래스 를 사용하는 방법에 대한 Top 9 FAQ를 요약 한 것 입니다. 간단히하기 위해 예제 에서는 generics 를 사용 합니다. 그러므로 나는 단지 Map구체적인 것 대신에 쓸 것이다 Map. 하지만 당신은 항상 모두 있다고 가정 할 수 있습니다 K 와 V가 의미하는 필적 K extends Comparable하고 V extends Comparable.

0. Convert a Map to a List

Java에서 Map 인터페이스는 키 세트, 값 세트 및 키 - 값 세트의 세 가지 콜렉션보기를 제공합니다. 이들 모두는 생성자 또는 addAll () 메소드 를 사용하여 List 로 변환 할 수 있습니다 . 다음 코드 스 니펫은 맵에서 ArrayList 를 생성하는 방법을 보여줍니다 .

// key list
List keyList = new ArrayList(map.keySet());
// value list
List valueList = new ArrayList(map.values());
// key-value list
List entryList = new ArrayList(map.entrySet());

1. Iterate over a Map

키 - 값의 모든 쌍을 반복하는 것은지도를 통과하는 가장 기본적인 작업입니다. Java에서 이러한 쌍은 Map.Entry 라는 맵 항목에 저장됩니다 . 지도 . entrySet () 은 키 - 값 세트를 반환하므로 맵의 모든 항목을 통과하는 가장 효율적인 방법은 다음과 같습니다.

for(Entry entry: map.entrySet()) {
  // get 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 key
  K key = entry.getKey();
  // get value
  V value = entry.getValue();
}

2. Sort a Map on the keys

키에 맵을 정렬하는 것은 또 다른 빈번한 조작입니다. 한 가지 방법은 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 을 사용하는 것입니다. SortedMap 은 키에 대한 전체 정렬을 제공합니다. 따라서 모든 키는 Comparable을 구현 하거나 비교 자에서 받아 들여야합니다.

SortedMap의 구현 클래스의 1 개 는 TreeMap 입니다. 생성자는 비교자를 받아 들일 수 있습니다. 다음 코드는 일반지도를 정렬 된지도로 변환하는 방법을 보여줍니다.


SortedMap sortedMap = new TreeMap(new Comparator() {
 
  @Override
  public int compare(K k1, K k2) {
    return k1.compareTo(k2);
  }
 
});
sortedMap.putAll(map);

3. Sort a Map on the values

Map을 목록에 넣고 정렬하면이 경우에도 작동하지만 항목 을 비교해야합니다 . 이번에는 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());
  }
 
});

값이 고유 한 경우에만이 질문에 대해 정렬 된지도를 계속 사용할 수 있습니다. 이러한 조건에서 key = value 쌍을 value = key로 바꿀 수 있습니다. 이 솔루션은 매우 강한 한계가 있으므로 나에게 권장되지 않습니다.

4. Initialize a static/immutable Map

Mapd이 일정하게 유지 될 것으로 예상되면 변경 불가능한지도에 복사하는 것이 좋습니다. 이러한 방어 프로그래밍 기술은 사용하기에 안전 할뿐만 아니라 쓰레드 맵에도 유용합니다.

정적 / 불변의 맵을 초기화하기 위해서, 정적 초기화를 사용할 수 있습니다 (아래처럼). 이 코드의 문제점은 map 이 static final 로 선언 되었지만 초기화 후에도 map을 작동 할 수 있다는 것 Test.map.put(3,"three");입니다. 그러므로 그것은 정말로 불변하지 않습니다. 정적 이니셜 라이저를 사용하여 변경 불가능한 맵을 작성하려면 추가 익명 클래스가 필요하며이를 초기화의 마지막 단계에서 수정할 수없는 맵으로 복사해야합니다. 두 번째 코드를 참조하십시오. 그런 다음 실행하면 UnsupportedOperationException 이 throw됩니다 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 라이브러리는 정적 및 변경 불가능한 컬렉션을 다양한 방법으로 지원합니다. 구아바의 불변 컬렉션 유틸리티의 이점에 대한 자세한 내용은 구아바 사용자 가이드의 불완전 컬렉션 설명을 참조하십시오.

5. HashMap, TreeMap 및 Hashtable의 차이점

Java 의 Map 인터페이스에는 HashMap , TreeMap 및 Hashtable 이라는 세 가지 주요 구현이 있습니다. 가장 중요한 차이점은 다음과 같습니다.

  1. 반복의 순서 . HashMap 과 Hashtable 은 맵의 순서를 보장하지 않습니다. 특히 주문이 시간이 지남에 따라 일정하게 유지된다는 것을 보장하지는 않습니다. 그러나 TreeMap 은 키의 "자연 순서"또는 비교 자에 따라 전체 항목을 반복합니다.
  2. 키 - 값 사용 권한. HashMap 은 null 키와 null 값을 허용합니다 (동일한 키가 허용되지 않으므로 하나의 null 키만 허용됩니다). Hashtable 은 null 키 또는 null 값을 허용하지 않습니다 . TreeMap 가 자연 순서 부를 사용하고있는 경우, 또는 Comparator가 null 키를 허가하지 않는 경우, 예외가 Throw됩니다.
  3. 동기화 됨 . Hashtable 만 동기화되고 다른 것은 동기화되지 않습니다. 따라서 스레드 안전 구현이 필요하지 않은 경우 Hashtable 대신 HashMap 을 사용하는 것이 좋습니다 .

더 완벽한 비교

                 | HashMap | Hashtable | TreeMap
-------------------------------------------------------
iteration order  | no      | no        | yes
null key-value   | yes-yes | no-no   | no-yes
synchronized     | no      | yes       | no
time performance | O(1)    | O(1)      | O(log n)
implementation   | buckets | buckets   | red-black tree

Read more about HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap.

6. A Map with reverse view/lookup

때로는 일련의 키 - 키 쌍이 필요합니다. 즉지도의 값이 키와 키 (일대일 맵)가 고유 함을 의미합니다. 이 제약 조건을 사용하여지도의 "역 조회 /보기"를 만들 수 있습니다. 그래서 우리는 그 가치로 열쇠를 찾을 수 있습니다. 이러한 데이터 구조를 양방향 맵 이라고 하는데, 불행하게도 JDK에서는이를 지원하지 않습니다.

Apache Common Collections와 Guava는 각각 BidiMap 및 BiMap 이라고하는 양방향 맵 구현을 제공합니다 . 둘 다 키와 값 사이에 1 : 1 관계가 있음을 제한합니다.

7. Shallow copy of a Map

java가 아닌 맵의 대부분의 구현은 다른 맵의 복사본 생성자를 제공합니다. 그러나 복사 절차는 동기화되지 않습니다 . 즉, 한 스레드가지도를 복사 할 때 다른 하나가 구조적으로 수정할 수 있습니다. [실수로 비동기 복사를 방지하려면 컬렉션을 사용해야합니다 . synchronizedMap () 을 미리 호출하십시오.

Map copiedMap = Collections.synchronizedMap(map);

shallow 복사의 또 다른 흥미로운 방법은 clone () 메서드를 사용 하는 것입니다. 그러나 Josh Bloch의 Java 콜렉션 프레임 워크 디자이너는 권장 하지 않습니다 . " 복제 생성자 대 복제 " 에 관한 대화 에서 그는

나는 사람들이 기대하기 때문에 종종 구체적인 클래스에 public clone 메소드를 제공한다. Cloneable이 망가 졌다는 것은 수치스러운 일이지만, 그것은 일어납니다. Cloneable은 약한 곳이며 사람들은 그 한계를 알고 있어야한다고 생각합니다.

이런 이유로 clone () 메서드를 사용 하여지도를 복사하는 방법을 알려주지 않습니다 .

8. Create an empty Map

맵이 불변 인 경우는,

map = Collections.emptyMap();

그렇지 않은 경우 구현을 사용하십시오. 예를 들어

map = new HashMap();


반응형

'웹프로그래밍 > Java' 카테고리의 다른 글

서버, 브라우저간의 변수  (0) 2017.11.23
Java exceptions  (0) 2017.11.22
Java Collections  (0) 2017.11.22
Java Strings  (0) 2017.11.22
Java Array  (0) 2017.11.22