重构Map地图的Java Map [英] Refactoring Java Map of Map of Map

查看:76
本文介绍了重构Map地图的Java Map的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在审查一个项目的旧代码,并使用 Map Map 获得数据结构。 地图(3层地图):

I'm reviewing an old code of an project and got a datastructure as bellow using Map of Map of Map(3-Layered Map):

// data structure
Map<String, Map<String, Map<String, List<String>>>> tagTree 
            = new HashMap<String, Map<String,Map<String,List<String>>>>();

并从Map中获取值(我认为这是不错的部分)

And fetch the values from Map (I think this is the nice part)

// 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 the values in Map (little bit complex and error-prone)

// 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);

目前这是用于维持以下结构

Currently this is serving to maintain following structure

TagLanguage - > TagStatus - > TagType - > TagList

TagLanguage -> TagStatus -> TagType -> TagList

我打算重构这个地图,因为对于其他开发者来说很难阅读。

I'm planning to refactor this Map because it's hard to read for other developers.

请分享您的想法如何通过考虑以下情况来做到这一点:

Please share your Idea How to do it by considering following cases:


  • 在运行时可以更改所有四个图层。

  • 所有级别应该是
    可访问

  • 需要内存中的解决方案,即不要使用数据库表层次结构。

推荐答案

如果您只想访问数据结构的最后一级,可以使用多重映射<三<字符串,字符串,字符串>,字符串> Multimap< K,V> 是来自Guava的数据结构,它基本上是一个更好的 Map< K,Collection< V>> Triple< L,M, R> 是来自Apache Commons Lang3的3元素元组数据结构, Comparable 并实现等于

If you only ever wanted to access the last level of your data structure, you could use a Multimap<Triple<String,String,String>,String>. Multimap<K,V> is a data structure from Guava which basically is a nicer Map<K,Collection<V>>. Triple<L,M,R> is a 3-elements tuple data structure from Apache Commons Lang3 which is Comparable and implements equals.

您可以像这样声明您的标记树:

You could declare your tag tree like this:

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"));

然后从中获取您的价值:

And then get your values from it like this:

Set<String> values = tagTree.get(Triple.of("Java", "Active", "Tags"));






这是另一个可能适合你的粗略解决方案可以使用1,2或3个键:


Here is another rough solution that may suit you which enables to get with 1, 2 or 3 keys:

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 方法返回的地图是可修改的

  • 我没有实现删除方法

  • 我没有经常测试

  • the maps that the get methods return are modifiable
  • I didn't implement remove methods
  • I didn't test it a lot

这篇关于重构Map地图的Java Map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆