Ответ 1
Итак, вам нужна поддержка отношений "многие ко многим"? Ближе всего вы можете получить Guava Multimap
как @Mechkov написал, но более конкретно Multimap
комбинация с Multimaps.invertFrom
. "BiMultimap" еще не реализован, но есть проблема, запрашивающая эту функцию в библиотеке Google Guava.
На этом этапе у вас есть несколько вариантов:
-
Если ваш "BiMultimap" будет неизменным, используйте
Multimaps.invertFrom
иImmutableMultimap
/ImmutableListMultimap
/ImmutableSetMultimap
(каждый из этих трех имеет разные значения хранения коллекции). Некоторый код (пример, взятый из приложения I, используетEnum
иSets.immutableEnumSet
):public class RolesAndServicesMapping { private static final ImmutableMultimap<Service, Authority> SERVICES_TO_ROLES_MAPPING = ImmutableMultimap.<Service, Authority>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<Authority, Service> ROLES_TO_SERVICES_MAPPING = SERVICES_TO_ROLES_MAPPING.inverse(); // before guava-11.0 it was: ImmutableMultimap.copyOf(Multimaps.invertFrom(SERVICES_TO_ROLES_MAPPING, HashMultimap.<Authority, Service>create())); public static ImmutableSet<Authority> getRoles(final Service service) { return Sets.immutableEnumSet(SERVICES_TO_ROLES_MAPPING.get(service)); } public static ImmutableSet<Service> getServices(final Authority role) { return Sets.immutableEnumSet(ROLES_TO_SERVICES_MAPPING.get(role)); } }
-
Если вы действительно хотите, чтобы ваш Multimap был модифицируемым, будет сложно поддерживать варианты K- > V и V- > K, если вы не будете изменять только
kToVMultimap
и вызыватьinvertFrom
каждый раз, когда вы хотите иметь свою инвертированную копию (и сделать эту копию немодифицируемой, чтобы убедиться, что вы случайно не изменяетеvToKMultimap
, что не будет обновлятьkToVMultimap
). Это не оптимально, но в этом случае должно быть сделано. -
(Не ваш случай, возможно, упоминается как бонус):
BiMap
интерфейс и классы реализации имеет метод.inverse()
, который даетBiMap<V, K>
вид изBiMap<K, V>
и сам послеbiMap.inverse().inverse()
. Если эта проблема, о которой я упоминал ранее, она, вероятно, будет иметь нечто похожее. -
(EDIT Октябрь 2016) Вы также можете использовать новый графический API, который будет присутствовать в Guava 20:
В целом, common.graph поддерживает графики следующих разновидностей:
- ориентированные графики
- неориентированные графики
- узлы и/или ребра со связанными значениями (веса, метки и т.д.)
- которые выполняют/не разрешают автопилы
- которые делают/не позволяют параллельные ребра (графики с параллельными ребрами иногда называют мультиграфами)
- чьи узлы/ребра упорядочиваются, сортируются или неупорядочены