我正在寻找一种存储键值对的方法。我需要查找是双向的,但同时我需要为同一个密钥存储多个值。换句话说,比如BidiMap,但是对于每个键,可以有多个值。例如,它需要能够保持像对象:“s1” - > 1,“s2” - > 1,“s3” - > 2,我需要能够获取映射到每个的值key,并为每个值获取与之关联的所有键。
答案 0 :(得分:20)
所以你需要支持多对多关系吗?你可以得到的最近的是Guava的Multimap
,就像@Mechkov写的那样 - 但更具体的是Multimap
与Multimaps.invertFrom
的组合。 “BiMultimap”尚未实现,但有an issue在Google Guava库中请求此功能。
此时你几乎没有选择:
如果你的“BiMultimap”是不可变的常量 - 使用Multimaps.invertFrom
和ImmutableMultimap
/ ImmutableListMultimap
/ ImmutableSetMultimap
(每个人都有不同的收藏存储值)。一些代码(从我开发的应用程序中获取的示例,使用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可以修改,除非您只修改kToVMultimap
并调用{{{}},否则很难同时维护K-> V和V-> K变体1}}每次你想要它的反转副本(并使该副本不可修改,以确保你不小心不修改invertFrom
什么不会更新vToKMultimap
)。这不是最佳选择,但在这种情况下应该这样做。
(可能不是你的情况,作为奖励提到):BiMap
接口和实现类有kToVMultimap
方法,它在.inverse()
之后提供BiMap<V, K>
视图BiMap<K, V>
。如果我之前提到的this issue完成了,它可能会有类似的东西。
(2016年10月编辑)您还可以使用new graph API中出现的Guava 20:
作为一个整体,common.graph支持以下类型的图表:
- 有向图
- 无向图
- 具有关联值(权重,标签等)的节点和/或边缘
- 允许/不允许自我循环的图表
- 允许/不允许平行边的图(具有平行边的图有时称为多图)
- 其节点/边缘是插入排序,排序或无序的图表
答案 1 :(得分:1)
有两张地图,键 - >值,值 - >键有什么问题?
答案 2 :(得分:1)
我希望使用MultivaluedMap解决问题。 请在下面的链接中找到oracle的文档。
http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/MultivaluedMap.html
答案 3 :(得分:1)
使用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方法
答案 4 :(得分:-2)
希望我帮到你了
class A {
long id;
List<B> bs;
}
class B {
long id;
List<A> as;
}
答案 5 :(得分:-3)
谷歌的Guava MultiMap实现就是我用于这些目的的。
Map<Key Collection<Values>>
其中Collection可以是ArrayList,例如。它允许将存储在集合中的多个值映射到键。 希望这有帮助!