Map<K, V> 컬렉션 인터페이스

jaegeunsong97·2023년 1월 21일
0
post-thumbnail

2023_1_21_TIL

Map<K, V> 컬렉션의 특징

  • Key와 Value 한 쌍으로 데이터를 저장
    • 한 쌍의 데이터를 'Entry' -> Map.Entry 타입으로 정의
    • Map<K, V>는 데이터를 엔트리 단위로 입력받는 것
  • Key는 중복 저장불가, Value는 중복 가능

Map<K, V> 인터페이스의 주요 메소드


  • Map<K, V>는 Key들을 Set형으로 관리 -> 중복이 안되는 이유!!!!
  • remove()
    • 매개변수 1개(key) -> 해당 키를 포함하는 엔트리 삭제
    • 매개변수 2개(key, value) -> 2개다 맞는 엔트리 삭제

HashMap<K, V>

  • Key값을 HashSet< E >으로 구현한 Map<K, V> 객체
  • 단일 스레드용
  • 입출력 순서 Randomk(key가 set으로 관리되니까)
  • capacity -> 16(동적)
  • Key값의 중복 여부 check는 HashSet과 같다(Key를 HashSet< E > 형태로 관리하니까!!)
    • key객체의 hashCode()비교 -> equals()비교
  • HashMap<K, V>의 주요 메소드
    • replace() -> 해당 key, value 가 없으면 작동 안함
    • keySet(), entrySet()
Set<Integer> keySet = hMap2.keySet();
Set<Map.Entry<Integer, String>> entrySet = hMap2.entrySet();
// Map<K, V>에 포함된 모든 엔트리를 set<E>로 가져올 수도 있다
// 즉, Set<E> 객체의 원소 타입이 바로 엔트리
// 리턴타입이 Set<Map.Enret<K, V>>
public class HashMapMethod {
    public static void main(String[] args) {
        Map<Integer, String> hMap1 = new HashMap<>();
        hMap1.put(2, "나다라");
        hMap1.put(1, "가나다");
        hMap1.put(3, "다라마");
        System.out.println(hMap1);

        Map<Integer, String> hMap2 = new HashMap<>();
        hMap2.putAll(hMap1);
        System.out.println(hMap2);

        hMap2.replace(1, "가가가");
        hMap2.replace(4, "라라라");
        System.out.println(hMap2);

        hMap2.replace(1, "가가가", "나나나");
        hMap2.replace(2, "다다다", "라라라");
        System.out.println(hMap2);

        System.out.println(hMap2.get(1));
        System.out.println(hMap2.get(2));
        System.out.println(hMap2.get(3));

        System.out.println(hMap2.containsKey(1));
        System.out.println(hMap2.containsKey(5));

        System.out.println(hMap2.containsValue("나나나"));
        System.out.println(hMap2.containsValue("다다다"));

        Set<Integer> keySet = hMap2.keySet();
        System.out.println(keySet);

        Set<Map.Entry<Integer, String>> entrySet = hMap2.entrySet();
        System.out.println(entrySet);

        System.out.println(hMap2.size());

        hMap2.remove(1);
        hMap2.remove(4);
        System.out.println(hMap2);

        hMap2.remove(2, "나다라");
        hMap2.remove(3, "다다다");
        System.out.println(hMap2);

        hMap2.clear();
        System.out.println(hMap2);
    }
}
  • HashMap<K, V> 중복 확인 메커니즘 -> HashSet< E >와 같음
class A {
    int data;
    public A(int data) {
        this.data = data;
    }
}
class B {
    int data;
    public B(int data) {
        this.data = data;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof B) {
            this.data = ((B) obj).data;
            return true;
        }
        return false;
    }
}
class C {
    int data;
    public C(int data) {
        this.data = data;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof C) {
            this.data = ((C)obj).data;
            return true;
        }
        return false;
    }
    @Override
    public int hashCode() {
        return Objects.hash(data);
    }
}

public class HashMapMachanism {
    public static void main(String[] args) {
        Map<A, String> hashMap1 = new HashMap<>();
        A a1 = new A(3);
        A a2 = new A(3);
        System.out.println(a1 == a2);
        System.out.println(a1.equals(a2));
        System.out.println(a1.hashCode() + ", " + a2.hashCode());
        hashMap1.put(a1, "첫번쨰");
        hashMap1.put(a2, "두번쨰");
        System.out.println(hashMap1.size());
        System.out.println(hashMap1);

        Map<B, String> hashMap2 = new HashMap<>();
        B b1 = new B(3);
        B b2 = new B(3);
        System.out.println(b1 == b2);
        System.out.println(b1.equals(b2));
        System.out.println(b1.hashCode() + ", " + b2.hashCode());
        hashMap2.put(b1, "첫번쨰");
        hashMap2.put(b2, "두번쨰");
        System.out.println(hashMap2.size());
        System.out.println();

        Map<C, String> hashMap3 = new HashMap<>();
        C c1 = new C(3);
        C c2 = new C(3);
        System.out.println(c1 == c2);
        System.out.println(c1.equals(c2));
        System.out.println(c1.hashCode() + ", " + c2.hashCode());
        hashMap3.put(c1, "첫번째");
        hashMap3.put(c2, "두번째");
        System.out.println(hashMap3.size());

    }
}

Hashtable<K, V>

  • 멀티스레드용 -> 내부에 synchronized 메소드로 구현
  • Hashtable<K, V>의 주요 메소드
    • 멀티스레드에 안정성을 가지는 것 제외하고 HashMap<K, V>와 동일한 특징
    • 동일한 Key값의 중복 X + 입출력순서 Random

LinkedHashMap<K, V>

  • HashMap<K, V>특성에 데이터의 순서 정보를 추가한 것
  • 입출력 순서대로 출력
  • HashMap<K, V>의 Key는 HashSet< E >로 관리
    • LinkedHashMap<K, V>의 Key는 LinkedHashSet< E >로 관리
      • Key의 순서정보를 갖고 있어서 Key값을 기반으로 출려되는 LinkedHashMap<K, V> 또한 순서 정보를 갖는 것
  • LinkedHashMap<K, V>의 주요 메소드
    • 입출력이 순서대로 나오는 것 빼고 HashMap<K, V>와 동일

TreeMap<K, V>

  • 데이터를 Key값의 크기순으로 저장(오름차순)
    • 반드시 Key객체의 크기 비교 기준 필요
    • SortedMap<K, V> NavigableMap<K, V> 인터페이스의 자식클래스
      • 정렬과 탐색 기능 추가
Map<Integer, String> treeMap = new TreeMap<>();
TreeMap<Integer, String> treeMap = new TreeMap<>();// 정렬 탐색 메소드 가능
  • TreeMap<K, V>의 주요 메소드
    • TreeSet과 매우 비슷, 단 데이터가 Entry형태로 저장되기 때문에 Key와 엔트리에 데이터를 검색하거나 추출하는 메소드가 포함되는 것

  • TreeMap<K, V>의 주요 메소드 사용하기
public class TreeMapMethod_1 {
    public static void main(String[] args) {
        TreeMap<Integer, String> treeMap = new TreeMap<>();
        for (int i = 20; i > 0; i -= 2) {
            treeMap.put(i, i + "번째 데이터");
        }
        System.out.println(treeMap);

        System.out.println(treeMap.firstKey());
        System.out.println(treeMap.firstEntry());
        System.out.println(treeMap.lastKey());
        System.out.println(treeMap.lastEntry());

        System.out.println(treeMap.lowerKey(11));
        System.out.println(treeMap.lowerKey(10));
        System.out.println(treeMap.lowerEntry(13));
        System.out.println(treeMap.lowerEntry(9));

        System.out.println(treeMap.higherKey(11));
        System.out.println(treeMap.higherKey(10));

        System.out.println(treeMap.pollFirstEntry());
        System.out.println(treeMap);

        System.out.println(treeMap.pollLastEntry());
        System.out.println(treeMap);

        SortedMap<Integer, String> sortedMap = treeMap.headMap(8);
        System.out.println(sortedMap);

        NavigableMap<Integer, String> navigableMap = treeMap.headMap(8, true);
        System.out.println(navigableMap);

        sortedMap = treeMap.tailMap(14);
        System.out.println(sortedMap);

        navigableMap = treeMap.tailMap(14, false);
        System.out.println(navigableMap);

        sortedMap = treeMap.subMap(6, 10);
        System.out.println(sortedMap);

        navigableMap = treeMap.subMap(6, false, 10, true);
        System.out.println(navigableMap);

        NavigableSet<Integer> navigableSet = treeMap.descendingKeySet();
        System.out.println(navigableSet);
        System.out.println(navigableSet.descendingSet());

        navigableMap = treeMap.descendingMap();
        System.out.println(navigableMap);
        System.out.println(navigableMap.descendingKeySet());
    }
}

// 사용자 클래스의 크기 비교 기준 제공
class MyClass {
    int data1;
    int data2;
    public MyClass(int data1 , int data2) {
        this.data1 = data1;
        this.data2 = data2;
    }
    @Override
    public String toString() {
        return "data1 = " + data1 + "을 갖고 있는 클래스";
    }
}
class MyComparableClass implements Comparable<MyComparableClass> {
    int data1;
    int data2;
    public MyComparableClass(int data1, int data2) {
        this.data1 = data1;
        this.data2 = data2;
    }
    @Override
    public int compareTo(MyComparableClass o) {
        if (this.data1 < o.data1) return -1;
        else if (this.data1 == o.data1) return 0;
        else return 1;
    }
    @Override
    public String toString() {
        return "data1 = " + data1 + "을 갖고 있는 클래스";
    }
}
public class TreeMapMethod_2 {
    public static void main(String[] args) {
        TreeMap<Integer, String> treeMap1 = new TreeMap<>();
        Integer intValue1 = new Integer(20);
        Integer intValue2 = new Integer(10);
        treeMap1.put(intValue1, "가나다");
        treeMap1.put(intValue2, "나라다");
        System.out.println(treeMap1);

        TreeMap<String, Integer> treeMap2 = new TreeMap<>();
        String str1 = "가나";
        String str2 = "다라";
        treeMap2.put(str1, 10);
        treeMap2.put(str2, 20);
        System.out.println(treeMap2);

        /*
        TreeMap<MyClass, String> treeMap3 = new TreeMap<>();
        MyClass myClass1 = new MyClass(2, 5);
        MyClass myClass2 = new MyClass(3, 3);
        treeMap3.put(myClass1, "가나다");
        treeMap3.put(myClass2, "나라다");
        System.out.println(treeMap3);
        */

        //
        TreeMap<MyComparableClass, String> treeMap4 = new TreeMap<>();
        MyComparableClass myComparableClass1 = new MyComparableClass(2, 5);
        MyComparableClass myComparableClass2 = new MyComparableClass(3, 3);
        treeMap4.put(myComparableClass1, "가나다");
        treeMap4.put(myComparableClass2, "나라다");
        System.out.println(treeMap4);

        //
        TreeMap<MyClass, String> treeMap5 = new TreeMap<>(new Comparator<MyClass>() {
            @Override
            public int compare(MyClass o1, MyClass o2) {
                if (o1.data1 < o2.data1) return -1;
                else if (o1.data1 == o2.data1) return 0;
                else return 1;
            }
        });
        MyClass myClass1 = new MyClass(2, 5);
        MyClass myClass2 = new MyClass(3, 3);
        treeMap5.put(myClass1, "가나다");
        treeMap5.put(myClass2, "나라다");
        System.out.println(treeMap5);
    }
}

참조

https://velog.io/@hj_/Java-Collection

profile
현재 블로그 : https://jasonsong97.tistory.com/

0개의 댓글