Java中的双向多值映射
我正在寻找一种存储键值对的方法。我需要双向查找,但同时需要为同一个键存储多个值。换句话说,类似于BidiMap,但每个键都可以有多个值。例如,它需要能够容纳像“s1”->1,“s2”->1,“s3”->2这样的对,我需要能够得到映射到每个键的值,并且对于每个值,得到与它相关的所有键。希望我答对了Java中的双向多值映射,java,multimap,Java,Multimap,我正在寻找一种存储键值对的方法。我需要双向查找,但同时需要为同一个键存储多个值。换句话说,类似于BidiMap,但每个键都可以有多个值。例如,它需要能够容纳像“s1”->1,“s2”->1,“s3”->2这样的对,我需要能够得到映射到每个键的值,并且对于每个值,得到与它相关的所有键。希望我答对了 class A { long id; List<B> bs; } class B { long id; List<A> as; } A类{ 长
class A {
long id;
List<B> bs;
}
class B {
long id;
List<A> as;
}
A类{
长id;
名单b;
}
B类{
长id;
列为;
}
有两个地图,键->值,值->键有什么不对?我正使用谷歌的Guava MultiMap实现来实现这些目的
Map<Key Collection<Values>>
Map
例如,其中集合可以是ArrayList。它允许将存储在集合中的多个值映射到一个键。
希望这有帮助 那么您需要支持多对多关系?你能得到的最接近的是@Mechkov写的——但更具体地说是
Multimap
与的组合。“BiMultimap”还没有实现,但Google Guava库中有此功能的请求
此时,您几乎没有选择:
Multimaps.invertFrom
和ImmutableMultimap
/ImmutableListMultimap
/ImmutableSetMultimap
(这三者中的每一个都有不同的集合存储值)。一些代码(示例取自我开发的应用程序,使用Enum
s和set.immutableEnumSet
):
公共类角色和服务映射{
私有静态最终不可变多重映射服务\u到\u角色\u映射=
ImmutableMultimap.builder()
.put(Service.SFP1、Authority.ROLE\u PREMIUM)
.put(Service.SFP、Authority.ROLE\u PREMIUM)
.put(Service.SFE、Authority.ROLE\u额外)
.put(Service.SF、Authority.ROLE_标准)
.put(Service.SK、Authority.ROLE_标准)
.put(Service.SFP1,Authority.ROLE_ADMIN)
.put(Service.ADMIN、Authority.ROLE\u ADMIN)
.put(Service.NONE、Authority.ROLE\u DENY)
.build();
//整个魔法就在这里:
私有静态最终ImmutableMultimap接口和实现类具有.inverse()
方法,该方法在BiMap
和BiMap.inverse().inverse()
之后提供BiMap
视图和自身。如果我前面提到过,它可能会有类似的内容
- 有向图
- 无向图
- 具有关联值(权重、标签等)的节点和/或边
- 允许/不允许自循环的图
- 允许/不允许平行边的图(具有平行边的图有时称为多重图)
- 节点/边按插入顺序、排序或无序排列的图
我希望使用多值映射解决这个问题。 请在下面的链接中找到来自oracle的文档
使用谷歌番石榴,我们可以编写一个原始的双模图,如下所示
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 + "]";
}
}
import java.util.Collection;
导入com.google.common.collect.ArrayListMultimap;
导入com.google.common.collect.Multimap;
公共类双乘法映射{
Multimap keyToValue=ArrayListMultimap.create();
Multimap valueToKey=ArrayListMultimap.create();
公共无效putForce(K键,V值){
keyToValue.put(键,值);
valueToKey.put(值,键);
}
公开作废认沽权(K键,V值){
集合oldValue=keyToValue.get(键);
if(oldValue.contains(value)==false){
keyToValue.put(键,值);
valueToKey.put(值,键);
}
}
公共集合getValue(K键){
返回keyToValue.get(key);
}
公共集合getKey(V值){
返回valueToKey.get(值);
}
@凌驾
公共字符串toString(){
返回“BiMultiMap[keyToValue=“+keyToValue+”,valueToKey=“+valueToKey+””;
}
}
希望这将有助于一些基本的双向多地图的需求。
注意K和V需要正确地实现hascode和equals方法您谈到每个键需要有多个值,但在您的示例中,您没有包含多个值的键,而是一个包含两个键的值。您可能应该澄清这一点。如果您的示例适合您的问题,您将得到更好的答案;-)在这里您可以找到方法创造multimap@pushy,同样的问题,如果我反转映射,将整数保留为键而不是值,我将得到一对多映射。无论如何,感谢您的更正。:)我认为保留相同数据的两个副本更容易出错。无论如何,在我查看了所有集合之后,我开始认为它是最好的解决方案。只需为地图创建一个使其保持同步的包装器。我不喜欢这个答案所认可的方法。这有很多潜在的错误,包括可能重新发明轮子、编写自己的错误、线程安全等。这是一个接口。有实现吗?你太聪明了,不适合这样做我甚至不记得回答过这个问题
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 + "]";
}
}