Двунаправленная многозначная карта в Java

Я ищу способ хранения пар ключ-значение. Мне нужно, чтобы поиск был двунаправленным, но в то же время мне нужно сохранить несколько значений для одного и того же ключа. Другими словами, что-то вроде BidiMap, но для каждого ключа может быть несколько значений. Например, он должен иметь возможность удерживать пары, такие как: «s1» -> 1, «s2» -> 1, «s3» -> 2, и мне нужно получить значение, сопоставленное каждому ключу, и для каждого значения, получите все связанные с ним ключи.

    6 Solutions collect form web for “Двунаправленная многозначная карта в Java”

    Итак, вам нужна поддержка отношений «многие ко многим»? Ближе всего вы можете получить Multimap Guava , как @Mechkov написал, но более конкретно Multimap сочетание с Multimaps.invertFrom . «BiMultimap» еще не реализован, но есть проблема с запросом этой функции в библиотеке Google Guava.

    На данный момент у вас есть несколько вариантов:

    1. Если ваш «BiMultimap» станет неизменным, используйте Multimaps.invertFrom и Multimaps.invertFrom / ImmutableListMultimap / ImmutableSetMultimap (каждый из этих трех имеет разные значения хранения коллекции). Некоторый код (пример, взятый из приложения, которое я разрабатываю, использует Enum s и Sets.immutableEnumSet ):

       public class RolesAndServicesMapping { private static final ImmutableMultimap SERVICES_TO_ROLES_MAPPING = ImmutableMultimap.builder() .put(Service.SFP1, Authority.ROLE_PREMIUM) .put(Service.SFP, Authority.ROLE_PREMIUM) .put(Service.SFE, Authority.ROLE_EXTRA) .put(Service.SF, Authority.ROLE_STANDARD) .put(Service.SK, Authority.ROLE_STANDARD) .put(Service.SFP1, Authority.ROLE_ADMIN) .put(Service.ADMIN, Authority.ROLE_ADMIN) .put(Service.NONE, Authority.ROLE_DENY) .build(); // Whole magic is here: private static final ImmutableMultimap ROLES_TO_SERVICES_MAPPING = SERVICES_TO_ROLES_MAPPING.inverse(); // before guava-11.0 it was: ImmutableMultimap.copyOf(Multimaps.invertFrom(SERVICES_TO_ROLES_MAPPING, HashMultimap.create())); public static ImmutableSet getRoles(final Service service) { return Sets.immutableEnumSet(SERVICES_TO_ROLES_MAPPING.get(service)); } public static ImmutableSet getServices(final Authority role) { return Sets.immutableEnumSet(ROLES_TO_SERVICES_MAPPING.get(role)); } } 
    2. Если вы действительно хотите, чтобы ваш Multimap был модифицируемым, будет сложно поддерживать как варианты K-> V, так и V-> K, если вы не будете изменять только kToVMultimap и invertFrom вызову каждый раз, когда вы хотите иметь свою инвертированную копию (и скопируйте unmodifiable, чтобы убедиться, что вы случайно не изменяете vToKMultimap что бы не обновляло kToVMultimap ). Это не оптимально, но в этом случае должно быть сделано.

    3. (Не ваш случай, возможно, упоминается как бонус): интерфейс BiMap и реализующие classы имеют .inverse() который дает BiMap вид из BiMap и сам после biMap.inverse().inverse() , Если эта проблема, о которой я упоминал ранее, будет выполнена, она, вероятно, будет иметь нечто подобное.

    4. (EDIT, октябрь 2016 г.). Вы также можете использовать новый графический API, который будет присутствовать в Guava 20 :

      В целом, common.graph поддерживает графики следующих разновидностей:

      • ориентированные графики
      • неориентированные графики
      • узлы и / или ребра со связанными значениями (веса, метки и т. д.),
      • Графики, которые делают / не позволяют создавать собственные петли
      • графы, которые делают / не позволяют параллельные ребра (графики с параллельными ребрами иногда называют мультиграфами)
      • графы, узлы / ребра которых упорядочиваются, сортируются или неупорядочены

    Что случилось с наличием двух карт, ключей-> значений, значений-> ключей?

    Я надеюсь, что использование MultivaluedMap решает проблему. Пожалуйста, найдите документацию от oracleа ниже ссылки.

    http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/MultivaluedMap.html

    Используя Google Guava, мы можем написать примитивную BiMulitMap, как показано ниже.

     import java.util.Collection; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; public class BiMultiMap { Multimap keyToValue = ArrayListMultimap.create(); Multimap valueToKey = ArrayListMultimap.create(); public void putForce(K key, V value) { keyToValue.put(key, value); valueToKey.put(value, key); } public void put(K key, V value) { Collection oldValue = keyToValue.get(key); if ( oldValue.contains(value) == false ) { keyToValue.put(key, value); valueToKey.put(value, key); } } public Collection getValue(K key) { return keyToValue.get(key); } public Collection getKey(V value) { return valueToKey.get(value); } @Override public String toString() { return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]"; } } 

    Надеюсь, это поможет некоторым элементарным потребностям двунаправленной мультикарты. Обратите внимание, что K и V должны правильно реализовать метод hascode и equals

    Надеюсь, я тебе прав

     class A { long id; List bs; } class B { long id; List as; } 

    Реализация Google Guava MultiMap – это то, что я использую для этих целей.

     Map> 

    где Collection может быть ArrayList, например. Он позволяет сопоставить несколько значений, хранящихся в коллекции, с ключом. Надеюсь это поможет!

    Interesting Posts

    std :: fstream не создает файл

    Почему я получаю «Один или несколько типов, необходимых для компиляции динамического выражения, не могут быть найдены»?

    Отключить возможность извлечения внутренних жестких дисков

    Вызов awt Кадровые методы из подclassа

    try / catch + using, правильный синтаксис

    Microsoft Word 2010 сбой при открытии второго документа Word, пока он еще открыт

    Угловой ресурс AngularJS

    Твиттер Bootstrap Collapse Direction-Horizontal вместо вертикальной

    Есть ли простой способ удалить неиспользуемые зависимости из maven pom.xml?

    Как связать перечисление с элементом управления combobox в WPF?

    c #: Как использовать перечисление для хранения строковых констант?

    Общая ошибка произошла в GDI +, JPEG-изображении в MemoryStream

    Эквивалент BigInteger в Swift?

    Как установить разрешения по умолчанию для автомонтированных дисков FAT в Ubuntu 9.10?

    В чем разница между упорядоченной и сортированной коллекцией?

    Давайте будем гением компьютера.