Java什么数据结构最适合双向多值映射
What Java data structure is best for two-way multi-value mapping
我是 Java 的新手,我想知道哪种类型的数据结构最适合我的情况。我有一组数据,它们本质上是键值对,但是每个值可能对应多个键,每个键可能对应多个值。一个简化的例子是:
- 红苹果
- 青苹果
- 红草莓
- 绿葡萄
- 紫葡萄
考虑到上面的例子,我需要能够 return 我有什么颜色的苹果 and/or 我有什么红色水果。实际数据将根据输入文件动态生成,其中每组将包含 100-100,000 个值,每个值可能对应另一组中的数百个值。
存储和解析这些数据的最有效方法是什么?我更喜欢 java 尽可能原生的解决方案,而不是外部数据库之类的解决方案。
This question 是相关的,但我不确定如何在我的案例中应用该解决方案,因为我需要在两个方向上为每个键分配多个值。
由于 Map
中不能有重复键,您可以创建一个 Map<Key, List<Value>>
,或者如果可以,使用 Guava's Multimap
.
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("Red", "Apple");
multimap.put("Red", "Strawberry");
System.out.println(multimap.get("Red")); // Prints - [Apple, Strawberry]
但问题是你不能要求给定对象的键,如果我找到其他东西,我会继续寻找、制作和编辑,希望它能有所帮助。
不过,您可以通过迭代映射并找到对象的键来自己进行反向操作。
您可以创建自己的自定义数据结构
public class MultiValueHashMap<K, V> {
private HashMap<K, ArrayList<V>> multivalueHashMap = new HashMap<K, ArrayList<V>>();
public static void main(String[] args) {
MultiValueHashMap<String, String> multivaluemap = new MultiValueHashMap<String, String>();
multivaluemap.put("Red", "Apple");
multivaluemap.put("Green", "Apple");
multivaluemap.put("Red", "Strawberry");
multivaluemap.put("Green", "Grapes");
multivaluemap.put("Purple", "Grapes");
for(String k : multivaluemap.keySet()){
System.out.println(k + " : " + multivaluemap.get(k).toString());
}
}
public void put(K key, V value){
if (multivalueHashMap.containsKey(key)){
ArrayList<V> values = multivalueHashMap.get(key);
values.add(value);
}else{
ArrayList<V> values = new ArrayList<V>();
values.add(value);
multivalueHashMap.put(key, values);
}
}
public Set<K> keySet(){
return multivalueHashMap.keySet();
}
public ArrayList<V> get(K key){
return multivalueHashMap.get(key);
}
}
输出应该是
红色:[苹果、草莓]
紫色:[葡萄]
绿色:[苹果、葡萄]
我建议你使用Guava's Table结构。使用颜色作为行键,使用水果作为列键,反之亦然。具体来说,HashBasedTable
非常适合您的情况。
根据您的用例,您不需要为值存储任何内容。但是,这些 Table
不允许 null
值。您可以使用虚拟 Boolean
或任何其他统计有用值,即插入日期和时间、用户、color/fruit 对数等
Table
有你需要的方法,比如column()
和row()
。请记住,文档说这些结构针对 行访问 进行了优化。如果您计划通过一个键访问多于另一个键,这对您来说可能没问题。
我是 Java 的新手,我想知道哪种类型的数据结构最适合我的情况。我有一组数据,它们本质上是键值对,但是每个值可能对应多个键,每个键可能对应多个值。一个简化的例子是:
- 红苹果
- 青苹果
- 红草莓
- 绿葡萄
- 紫葡萄
考虑到上面的例子,我需要能够 return 我有什么颜色的苹果 and/or 我有什么红色水果。实际数据将根据输入文件动态生成,其中每组将包含 100-100,000 个值,每个值可能对应另一组中的数百个值。
存储和解析这些数据的最有效方法是什么?我更喜欢 java 尽可能原生的解决方案,而不是外部数据库之类的解决方案。
This question 是相关的,但我不确定如何在我的案例中应用该解决方案,因为我需要在两个方向上为每个键分配多个值。
由于 Map
中不能有重复键,您可以创建一个 Map<Key, List<Value>>
,或者如果可以,使用 Guava's Multimap
.
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("Red", "Apple");
multimap.put("Red", "Strawberry");
System.out.println(multimap.get("Red")); // Prints - [Apple, Strawberry]
但问题是你不能要求给定对象的键,如果我找到其他东西,我会继续寻找、制作和编辑,希望它能有所帮助。
不过,您可以通过迭代映射并找到对象的键来自己进行反向操作。
您可以创建自己的自定义数据结构
public class MultiValueHashMap<K, V> {
private HashMap<K, ArrayList<V>> multivalueHashMap = new HashMap<K, ArrayList<V>>();
public static void main(String[] args) {
MultiValueHashMap<String, String> multivaluemap = new MultiValueHashMap<String, String>();
multivaluemap.put("Red", "Apple");
multivaluemap.put("Green", "Apple");
multivaluemap.put("Red", "Strawberry");
multivaluemap.put("Green", "Grapes");
multivaluemap.put("Purple", "Grapes");
for(String k : multivaluemap.keySet()){
System.out.println(k + " : " + multivaluemap.get(k).toString());
}
}
public void put(K key, V value){
if (multivalueHashMap.containsKey(key)){
ArrayList<V> values = multivalueHashMap.get(key);
values.add(value);
}else{
ArrayList<V> values = new ArrayList<V>();
values.add(value);
multivalueHashMap.put(key, values);
}
}
public Set<K> keySet(){
return multivalueHashMap.keySet();
}
public ArrayList<V> get(K key){
return multivalueHashMap.get(key);
}
}
输出应该是
红色:[苹果、草莓]
紫色:[葡萄]
绿色:[苹果、葡萄]
我建议你使用Guava's Table结构。使用颜色作为行键,使用水果作为列键,反之亦然。具体来说,HashBasedTable
非常适合您的情况。
根据您的用例,您不需要为值存储任何内容。但是,这些 Table
不允许 null
值。您可以使用虚拟 Boolean
或任何其他统计有用值,即插入日期和时间、用户、color/fruit 对数等
Table
有你需要的方法,比如column()
和row()
。请记住,文档说这些结构针对 行访问 进行了优化。如果您计划通过一个键访问多于另一个键,这对您来说可能没问题。