Проблема с BiMap и LinkedHashMap в Guava

Это возможно в Гуаве,

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

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

3 ответа

Решение

Объявление. 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"));
}

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

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

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,

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

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

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

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

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

Другие вопросы по тегам