[Java] Guava - MultiMap , BiMap

2024. 7. 14. 17:56·JVM/Java

개요

Guava 라이브러리에서 가장 자주 쓰이는 MultiMap과 BiMap 에 대해 알아본다.

 

MultiMap

key 하나에 여러 value 를 매핑하려고 할 때 쓰이는 인터페이스다.

Java 에서 제공하는 기본 Map<K,V> 의 Value 타입을 리스트로 직접 선언하여 다룰 수 있지만 단점이 있다.

  1. 문법이 장황해진다.
  2. 같은 key 에 값을 쓰면, 마지막 value 로 덮어써진다.
  class ListMap {
    @DisplayName("prolix list map")
    @Test
    void prolixListMapTest() {
      // given
      Map<String, List<String>> map = new HashMap<>();
      // 매번 값을 쓸 때마다 List 객체 생성을 명시해야 한다.
      map.put("Fruit", List.of("Banana"));
      // 가장 마지막에 put 된 값으로 overwrite
      map.put("Fruit", List.of("Apple"));
      // then
      assertThat(map.get("Fruit"))
        .hasSize(1)
        .isEqualTo(List.of("Apple"));
    }
  }

 

ArrayListMutliMap

언제 쓰나?

value 에 unique 함을 보장할 필요가 없을 때 사용한다.

value 는 ArrayList 타입으로 uniqueness 를 보장하지 않는다.

  class ArrayListMultiMapTest {
    @DisplayName("duplicates is allowed in a ArrayListMultiMap")
    @Test
    void multipleValuesTest() {
      // given
      Multimap<String, String> multiMap = ArrayListMultimap.create();
      // when
      multiMap.put("Fruit", "Apple");
      multiMap.put("Fruit", "Banana");
      multiMap.put("Fruit", "Banana");
      multiMap.put("Fruit", "Cherry");
      multiMap.put("Vegetable", "Carrot");
      // then
      assertAll(
        () -> assertThat(multiMap.keySet()).hasSize(2),
        () -> assertThat(multiMap.get("Fruit"))
          .hasSize(4)
          .containsAll(List.of("Apple", "Banana", "Banana", "Cherry"))
      );
    }
  }

 

MultiMap 으로 다음 장점을 얻는다.

  • 문법이 간결해진다.
    명시적으로 값을 쓸 때마다 List 객체를 생성할 필요가 없다.
    같은 key 에 여러 value 를 간단하게 담을 수 있다.

 

HashMultiMap

언제 쓰나?

value 가 unique 함을 보장해야 할 때 사용한다.

value 는 Set 타입으로 uniqueness 를 보장한다.

  class HashMultimapTest {
    @DisplayName("HashMultimap guarantees that the value is unique")
    @Test
    void duplicateTest() {
      // given
      Multimap<String, Long> multiMap = HashMultimap.create();
      // when
      multiMap.put("prices", 100L);
      multiMap.put("prices", 100L);
      multiMap.put("prices", 100L);

      // then
      assertThat(multiMap.get("prices"))
        .hasSize(1)
        .isEqualTo(Set.of(100L));
    }
  }

 

 

 

두 구현체 모두다 thread-safe 하지 않다.

 

BiMap

언제 쓰나?

Map의 <K, V> 는 K 만 가지고 값을 조회할 수 있다.

역방향인 V -> K 로 조회하는 API 를 제공한다.

 

public class BiMapTest {

  @DisplayName("BiMap allows getting the value inversely")
  @Test
  void getValueInverse() {
    // given
    BiMap<String, Integer> asciiBiMap = HashBiMap.create(5);
    asciiBiMap.put("A", 65);
    asciiBiMap.put("B", 66);
    asciiBiMap.put("C", 67);

    BiMap<Integer, String> inversedBiMap = asciiBiMap.inverse();
    // when then
    assertAll(
      () -> assertThat(inversedBiMap.get(65)).isEqualTo("A"),
      () -> assertThat(inversedBiMap.get(66)).isEqualTo("B"),
      () -> assertThat(inversedBiMap.get(67)).isEqualTo("C")
    );
  }

}

 

 

BiMap 은 `inverse()` 메소드로 역방향 Map 생성을 지원하는 자료구조기 때문에

Value 중복을 허용하지 않는다.

  @DisplayName("BiMap does not allow writing the duplicates because it can't be inverted when duplicates exists")
  @Test
  void duplicatesNotAllowedTest() {
    // given
    BiMap<String, Integer> asciiBiMap = HashBiMap.create(2);
    asciiBiMap.put("A", 65);
    assertThatThrownBy(
      // invert 하는 순간 65 -> A, B 가 되므로 중복 발생.
      // 허용되지 않는다.
      ()-> asciiBiMap.put("B", 65)
    ).isInstanceOf(IllegalArgumentException.class)
      .hasMessage("value already present: 65");
  }
저작자표시 (새창열림)

'JVM > Java' 카테고리의 다른 글

[Java] 예외 번역과 예외 연쇄 기법  (0) 2024.09.30
[Java] Thread 상속 대신 Runnable 을 사용하라.  (0) 2024.07.21
[Java] Generic vs WildCard  (2) 2024.01.07
[객체지향] 잘못된 DRY 원칙 적용  (0) 2023.12.16
[Java] Enum 에는 equals 대신 == 을 써라  (0) 2023.11.22
'JVM/Java' 카테고리의 다른 글
  • [Java] 예외 번역과 예외 연쇄 기법
  • [Java] Thread 상속 대신 Runnable 을 사용하라.
  • [Java] Generic vs WildCard
  • [객체지향] 잘못된 DRY 원칙 적용
M_Falcon
M_Falcon
  • M_Falcon
    Falcon
    M_Falcon
  • 전체
    오늘
    어제
    • 분류 전체보기 (430) N
      • Web (16)
        • Nodejs (14)
        • Javascript (23)
        • FrontEnd (4)
      • DataBase (39)
        • Fundamental (1)
        • Redis (4)
        • PostgreSQL (10)
        • NoSQL (4)
        • MySQL (9)
        • MSSQL (3)
        • Error (4)
      • Algorithm (79)
        • Algorithm (문제풀이) (56)
        • Algorithm (이론) (23)
      • JVM (65) N
        • Spring (13)
        • JPA (5)
        • Kotlin (13)
        • Java (24) N
        • Error (7)
      • 기타 (68)
        • Kafka (3)
        • Kubernetes (3)
        • Docker (12)
        • git (19)
        • 잡동사니 (26)
      • 재테크 (11)
        • 세무 (4)
        • 투자 (3)
        • 보험 (0)
      • BlockChain (2)
        • BitCoin (0)
      • C (32)
        • C (10)
        • C++ (17)
        • Error (3)
      • Low Level (8)
        • OS (3)
        • 시스템 보안 (5)
      • 네트워크 (3)
      • LINUX (30)
        • Linux (26)
        • Error (4)
      • 저작권과 스마트폰의 이해 (0)
      • 생각 뭉치 (6)
      • 궁금증 (2)
      • Private (4)
        • 이직 경험 (0)
        • 꿈을 찾아서 (1)
      • Android (21)
        • OS (4)
  • 블로그 메뉴

    • 홈
    • WEB
    • 알고리즘
    • DataBase
    • Linux
    • Mobile
    • C
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    javascript
    JPA
    Bitcoin
    linux
    algorithm
    java
    알고리즘
    Git
    kafka
    Kotlin
    database
    Spring
    android
    docker
    Programmers
    ubuntu
    PostgreSQL
    C++
    프로그래머스
    백준
  • hELLO· Designed By정상우.v4.10.3
M_Falcon
[Java] Guava - MultiMap , BiMap
상단으로

티스토리툴바