Я ищу способ хранения пар ключ-значение. Мне нужно, чтобы поиск был двунаправленным, но в то же время мне нужно сохранить несколько значений для одного и того же ключа. Другими словами, что-то вроде BidiMap, но для каждого ключа может быть несколько значений. Например, он должен иметь возможность удерживать пары, такие как: «s1» -> 1, «s2» -> 1, «s3» -> 2, и мне нужно получить значение, сопоставленное каждому ключу, и для каждого значения, получите все связанные с ним ключи.Двунаправленная многозначная карта в Java
ответ
Значит, вам нужна поддержка отношений «многие ко многим»? Ближе всего вы можете получить GuavaMultimap
как @Mechkov написал - но точнее Multimap
сочетание с Multimaps.invertFrom
. «BiMultimap» еще не реализован, но есть an issue, запрашивающий эту функцию в библиотеке Google Guava.
На данный момент у вас есть несколько вариантов:
Если ваш «BiMultimap» будет непреложной константы - использовать
Multimaps.invertFrom
иImmutableMultimap
/ImmutableListMultimap
/ImmutableSetMultimap
(каждый из theese трех имеет различные значения коллекции хранящих). Часть кода (пример взят из приложения I разработки, используетEnum
s и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()
. Если this issue, о котором я упомянул ранее, будет, похоже, что-то подобное.(EDIT октября 2016) Вы также можете использовать new graph API, которые будут присутствовать в Guava 20:
В целом, общий.График поддерживает графики следующих разновидностей:
- ориентированные графы
- неориентированных графов
- узлов и/или ребер с соответствующими значениями (весами, этикеток и т.д.)
- графиков, которые делают/не делают позволяют себя петле
- график, которые делают/не допускают параллельные кромок (графы с параллельными кромками иногда называют мультиграфы)
- графики, чьи узлы/края вставка упорядоченной, сортируются, или неупорядоченное
Надежда Я вам
class A {
long id;
List<B> bs;
}
class B {
long id;
List<A> as;
}
Что плохого в две карты, клавишные> значения с ценностно клавиш вправо,>?
Я думал, что сохранение двух копий одних и тех же данных будет более подверженным ошибкам. В любом случае, после всех коллекций, на которые я смотрел, я начинаю думать, что это лучшее решение. –
Просто создайте оболочку для карт, которые синхронизируют их. – Stefan
Мне не нравится подход, одобренный этим ответом. В этом есть много вещей, которые могут быть ошибочными, в том числе, возможно, изобретать колесо, писать собственные ошибки на этом пути, безопасность потоков и т. Д. – bacar
Реализация Guava MultiMap от Google - это то, что я использую для этих целей.
Map<Key Collection<Values>>
где Collection может быть ArrayList, например. Он позволяет сопоставить несколько значений, хранящихся в коллекции, с ключом. Надеюсь, это поможет!
Не двунаправленный. – Stefan
Я надеюсь, что с помощью MultivaluedMap решает эту проблему. Пожалуйста, найдите документацию от оракула ниже ссылки.
http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/MultivaluedMap.html
Это интерфейс. Есть ли какие-либо реализации? – amoebe
Использование Google Guava мы можем написать примитивную BiMulitMap, как показано ниже.
import java.util.Collection;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
public class BiMultiMap<K,V> {
Multimap<K, V> keyToValue = ArrayListMultimap.create();
Multimap<V, K> 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<V> oldValue = keyToValue.get(key);
if (oldValue.contains(value) == false) {
keyToValue.put(key, value);
valueToKey.put(value, key);
}
}
public Collection<V> getValue(K key) {
return keyToValue.get(key);
}
public Collection<K> getKey(V value) {
return valueToKey.get(value);
}
@Override
public String toString() {
return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]";
}
}
Надеюсь, это поможет некоторым элементарным потребностям двунаправленной карты. Обратите внимание, что K и V необходимо правильно реализовать метод hascode и equals
- 1. Двунаправленная карта на Java?
- 2. Двунаправленная карта
- 3. PHP Двунаправленная карта
- 4. Двунаправленная карта в Какао
- 5. Двунаправленная карта в clojure?
- 6. Двунаправленная карта в .NET
- 7. Двунаправленная карта в Riak
- 8. Есть двунаправленная карта в Matlab?
- 9. Многозначная логика в Z3
- 10. Есть ли 2-сторонняя (двунаправленная) карта в Qt?
- 11. Двунаправленная расширяемая иерархия с Java
- 12. Разработка кода Java двунаправленная связь
- 13. ListBox Многозначная строка для объекта
- 14. User.businessPhones Недвижимость многозначная?
- 15. Многозначная колонка в Oracle PLSQL
- 16. Многозначная грань в широколистной сети
- 17. Двунаправленная привязка данных в Java (программно)
- 18. Есть ли в Java одна ключевая и многозначная структура данных?
- 19. Возможна ли двунаправленная связь HCE?
- 20. многозначная группировка с xslt 2
- 21. многозначная ось с датами времени
- 22. Anorm поддержка многозначная не работает
- 23. Java: зашифрованный сервер/клиент двунаправленная связь?
- 24. Карта Java
- 25. Карта дженериков в Java
- 26. Коллекция Карта в Java
- 27. GPS-карта в java
- 28. Карта Коллекции в Java
- 29. Карта & HashMap в java
- 30. Карта делегатов в Java
Вы говорите о необходимости иметь несколько значений на ключ, но в вашем примере у вас нет ключа с несколькими значениями, но одно значение с двумя ключами. Вероятно, вы должны это разъяснить. Если ваш пример подходит к вашему вопросу, вы получите ответы на более точные ответы ;-) – pushy
http://www.jguru.com/faq/view.jsp?EID=1317828 здесь вы можете найти, как создать multimap – maks
@pushy, та же проблема, если я отменяю карту и сохраняю целые числа как ключи, а не как значения, я получаю отображение «один ко многим». Во всяком случае, спасибо за исправление. :) –