我正在查看一个项目的旧代码,并使用Map of Map of Map(3层地图)获得如下数据结构:
// data structure
Map<String, Map<String, Map<String, List<String>>>> tagTree
= new HashMap<String, Map<String,Map<String,List<String>>>>();并从Map中获取值(我认为这是很好的部分)
// fetch at tag values
List<String> tagList1 = tagTree.get("Java").get("Active").get("Tags");
List<String> tagList2 = tagTree.get("Java").get("Latest").get("SubTags");将值放在Map中(有点复杂且容易出错)
// put values
Map<String, Map<String, List<String>>> javaLangMap = new HashMap<String, Map<String, List<String>>>();
Map<String, List<String>> javaStatusMap = new HashMap<String, List<String>>();
List<String> javaTagList = new ArrayList<String>();
javaTagList.add("Java-OOP");
javaTagList.add("Java-Variables");
// put tag list
javaStatusMap.put("Tags", javaTagList);
// put status-wise tag
javaLangMap.put("Active", javaStatusMap);
// put language-wise tag
tagTree.put("Java", javaLangMap);目前,这将用于维护以下结构
TagLanguage -> TagStatus -> TagType -> TagList
我计划重构这个地图,因为对其他开发人员来说它很难理解。
请分享你的想法,如何通过考虑以下情况:
发布于 2016-03-27 08:35:57
如果您只想访问数据结构的最后一个级别,则可以使用Multimap<Triple<String,String,String>,String>。Multimap是一个来自番石榴的数据结构,基本上是一个更好的Map<K,Collection<V>>。Triple是Apache的三元素元组数据结构,Triple是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方法发布于 2016-03-27 07:15:40
您可以创建包含数据结构的类。
public class A {
Map<String, List<String>> map;
}
public class B {
Map<String, A> map;
}
Map<String, B> tagTree;发布于 2016-03-27 07:22:18
我不认为这是一个如此糟糕的解决方案。这只是一种树的表示法,对于每一片叶子都在3级的树来说。如果不是这样的话(不同的叶子级别,等等)。您必须建立一个树类结构。
但我要更改的是将所有内容放入一个类中,其中包含一个get和set方法,包括null-checks。
在下面的代码中,add方法负责处理容易出错的中间级别映射,而get在中间级别检查空值:
public class TreeStructure {
Map<String, Map<String, Map<String, List<String>>>> tagTree
= new HashMap<String, Map<String,Map<String,List<String>>>>();
// ... Constructor ...
// This method adds all intermediate levels if not existing
public void add(String level1, String level2, String level3) {
String l1 = tagTree.get(level1);
if(l1 == null)
tagTree.put(level1, new HashMap<String, Map<String, List<String>>>());
l1 = tagTree.get(level1);
String l2 = l1.get(level2),
if(l2 == null)
tagTree.put(level2, new Map<String, List<String>>(););
l2 = l1.get(level2);
String l3 = l2.get(level3);
if(l3 == null) l2.add(level3, new ArrayList<>());
}
// This method checks, if every intermediate level existed
// Otherwise, get() returns null, and the next get() would fail
public String get(String level1, String level2, String level3) {
String l1 = tagTree.get(level1);
if(l1 == null)
return null;
String l2 = l1.get(level2),
if(l2 == null)
return null;
l2 = l1.get(level2);
String l3 = l2.get(level3);
return l3;
}
}(未经测试的代码)
https://stackoverflow.com/questions/36244782
复制相似问题