Проблема с BiMap и LinkedHashMap в Guava - PullRequest
2 голосов
/ 12 марта 2012

Возможно ли в Гуаве,

  1. Провести обратный поиск в BiMap для ключевых и нескольких значений?Точно, у меня есть ключ и соответствующие несколько значений, я хочу получить ключ из значения.

  2. Чтобы сохранить несколько значений в LinkedHashMap?Точно, я хочу сохранить ключевые значения в определенном порядке, чтобы получить ключевую позицию в списке.

Ответы [ 3 ]

7 голосов
/ 12 марта 2012

Ad.1. Да, можно выполнить обратный поиск с BiMap<K, V>, просто позвоните inverse на свой BiMap и вы получите инвертированный BiMap<V, K> просмотр вашего BiMap.

Пример (взят из набора тестов Guava):

public void testMapConstructor() {
  /* Test with non-empty Map. */
  Map<String, String> map = ImmutableMap.of(
      "canada", "dollar",
      "chile", "peso",
      "switzerland", "franc");
  HashBiMap<String, String> bimap = HashBiMap.create(map);
  assertEquals("dollar", bimap.get("canada"));
  assertEquals("canada", bimap.inverse().get("dollar"));
}

Ad.2. Предполагая, что вы имеете в виду "Я хочу сохранить, ключ -> несколько значений [collection]" (Map<K, Collection<V>>), ListMultimap, вероятно, то, что вы хотите,точнее ArrayListMultimap (сохраняет порядок значений) или LinkedListMultimap (сохраняет порядок ключей и значений).Если ваш объект будет неизменным, я настоятельно советую вам использовать ImmutableListMultimap.

Вы также можете создать собственную реализацию Multimap, используя factory (немного многословно), то есть я использую:

private static <K, V> ListMultimap<K, V> makeLinkedArrayListMultimap() {
  return Multimaps.newListMultimap(Maps.<K, Collection<V>>newLinkedHashMap(), 
      new Supplier<List<V>>() {
        @Override public List<V> get() {
          return Lists.newArrayList();
        }
      });
}

public static void main(final String[] args) {
  final ListMultimap<String, String> multimap = makeLinkedArrayListMultimap();
  multimap.putAll("one", ImmutableList.of("zero", "three"));
  multimap.putAll("two", ImmutableList.of("three", "four", "three"));
  multimap.putAll("three", ImmutableList.<String>of()); // note that this doesn't add key to multimap
  multimap.put("four", "forty-two");

  System.out.println(multimap);
  // prints {one=[one, three], two=[three, four, three], four=[forty-two]}

  final List<String> listForOnes = multimap.get("one");
  System.out.println(listForOnes.get(0));
  // prints zero
}

PS Взгляните на вики Guava , который объясняет как BiMap, так и Multimap.

3 голосов
/ 12 марта 2012

Как @ Xaerxess говорит в свой ответ на ваш 2-й вопрос, вы можете создать свой собственный ListMultimap, который использует LinkedHashMap в качестве вспомогательной карты, используя Multimaps.newListMultimapmethod.

Для вашего первого вопроса, где у вас есть ключи, сопоставленные с несколькими значениями (например, Multimap), вы можете использовать метод Multimaps.invertFrom, чтобы создать инвертированную копию вашегооригинал Multimap для обратного поиска.Кроме того, вы можете создать ImmutableListMultimap копию оригинала и использовать его метод inverse(), чтобы получить обратное, хотя это просто скопировать оригинал, как это делает Multimaps.invertFrom (хотя он будет кешировать его, поэтому повторные вызовы inverse() вернуть ту же копию.)

Это, вероятно, того стоит, если вы не возражаете против дополнительного потребления памяти, хотите выполнить несколько обратных обращений и вам не нужна обратная копия, чтобы остатьсяпоследние изменения в оригинале, которые происходят после его создания.Если вы просто хотите найти ключи, которые соответствуют одному конкретному значению, вы можете сделать это за одну итерацию записей без создания полной копии.

3 голосов
/ 12 марта 2012

Ближайшим в Гуаве является Multiset для сопоставления нескольких значений с ключом, но я сомневаюсь, что оно удовлетворяет вашим требованиям.

  1. Я сомневаюсь, что это хорошая идея, чтобы найтиключ с использованием значений (если у вас есть несколько значений, сопоставленных с одним ключом), чтобы сделать это, ваше значение должно быть уникальным и, учитывая вашу структуру данных (например, Map<Key, Collection<Value>), не может быть гарантировано наличие уникальных значений.
  2. Другой вариант с гуавой - это BiMap, который требует уникальных значений и может обеспечить обратное сопоставление (значение -> ключ), но поскольку вам необходимо сопоставить несколько значений с одним и тем же ключом, этотоже не очень подходит.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...