如果你只想访问数据结构的最后一层,你可以使用一个
Multimap<Triple<String,String,String>,String>
。
Multimap<K,V>
是来自Guava的数据结构,基本上是一个更好的
Map<K,Collection<V>>
。
Triple<L,M,R>
是来自Apache Commons Lang3的三元组数据结构,它是
Comparable
并实现了
equals
。
你可以像这样声明你的标记树:
Multimap<Triple<String, String, String>, String> tagTree = HashMultimap.create();
然后像这样填写:
tagTree.put(Triple.of("Java", "Active", "Tags"), "Java-OOP");
tagTree.put(Triple.of("Java", "Active", "Tags"), "Java-Variables");
或:
tagTree.putAll(Triple.of("Java", "Active", "Tags"), Arrays.asList("Java-OOP", "Java-Variables"))
然后像这样从中获取您的值:
Set<String> values = tagTree.get(Triple.of("Java", "Active", "Tags"))
这里有另一种可能适合您的简易解决方案,可以使用1、2或3个键获取:
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
public class ThreeLevelMap<K1, K2, K3, V> {
private Map<K1, Map<K2, Multimap<K3, V>>> firstLevelMap = new HashMap<>();
private Map<Pair<K1, K2>, Multimap<K3, V>> secondLevelMap = new HashMap<>();
private Multimap<Triple<K1, K2, K3>, V> thirdLevelMap = HashMultimap.create();
public void put(K1 key1, K2 key2, K3 key3, V value) {
thirdLevelMap.put(Triple.of(key1, key2, key3), value);
final Pair<K1, K2> secondLevelKey = Pair.of(key1, key2);
Multimap<K3, V> secondLevelContainer = secondLevelMap.get(secondLevelKey);
if (secondLevelContainer == null) {
secondLevelContainer = HashMultimap.create();
secondLevelMap.put(secondLevelKey, secondLevelContainer);
}
secondLevelContainer.put(key3, value);
Map<K2, Multimap<K3, V>> firstLevelContainer = firstLevelMap.get(key1);
if (firstLevelContainer == null) {
firstLevelContainer = new HashMap<>();
firstLevelMap.put(key1, firstLevelContainer);
}
firstLevelContainer.put(key2, secondLevelContainer);
}
public Collection<V> get(K1 key1, K2 key2, K3 key3) {
return thirdLevelMap.get(Triple.of(key1, key2, key3));
}
public Multimap<K3, V> get(K1 key1, K2 key2) {
return secondLevelMap.get(Pair.of(key1, key2));
}
public Map<K2, Multimap<K3, V>> get(K1 key1) {
return firstLevelMap.get(key1);
}
}
您可以这样使用它:
ThreeLevelMap<String, String, String, String> tlm = new ThreeLevelMap<>();
tlm.put("Java", "Active", "Tags", "Java-OOP");
tlm.put("Java", "Active", "Tags", "Java-Variables");
Map<String, Multimap<String, String>> firstLevelMap = tlm.get("Java");
Multimap<String, String> secondLevelMap = tlm.get("Java", "Active");
Collection<String> tags = tlm.get("Java", "Active", "Tags");
我认为这是粗略的原因是:
get
方法返回的地图是可修改的
- 我没有实现
remove
方法
- 我没有进行大量测试