有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在java中选择用值列表组织数据的数据结构

我有一个如下所示的映射,其中有一个键,值的类型为List

Map<String, List<String> newdatamap = new HashMap<>();
map.put ("RtyName", Arrays.asList("wpn", "wpfnb", "dgeft", "xbthy"));
map.put ("rtyRate", Arrays.asList("dd", "ww", "trrty", "httyure"))

我想在前面的地图上再添加一个地图,这样就有一个键,它的值就是上面的地图。这是正确的数据结构吗?我们如何实现它

我想要如下所示的东西

Key         Value

B1          RtyName  ----> "weepn", "weepfnb", "eedgeft", "xbteehy"
            rtyRate ----->"deed", "ww", "terrty", "hteetyure"



B2          RtyName  ----> "SSSweepn", "wpefSSSnb", "GGeGdgeft", "xbteYYYYhy"
            rtyRate ----->"WWded", "wTeTYw", "YYYYtrerty", "IIIehttyure"

如上所示,只向映射引入了一个新键,其值为上一个映射

因此,它就像一个Map<String, Map<String, List<String>>>变成了一个复杂的数据结构,我可以将数据结构组织为 例如,一个类包含一个映射,因此

Map<B1 , RtyName>
Map<B2 ,rtyRate>

和付款人nae包含值列表,例如

 RtyName  ----> "SSSweepn", "wpefSSSnb", "GGeGdgeft", "xbteYYYYhy"
  rtyRate ----->"deed", "ww", "terrty", "hteetyure"

因此,在上述结构中,复杂性将较低,因为在B1的末尾,我必须搜索将为RtyName的键,并根据付款人名称进一步搜索将为“wpn”、“wpfnb”、“dgeft”、“xbthy”的值

请告知什么样的地图是最好的,或者是否有其他更好的数据结构来获取此信息

我脑海中浮现的一个数据结构是番石榴表

  final Table<String, String, List<String>> values = HashBasedTable.create();
values.put("B1", "RtyName", Lists.newArrayList("weepn", "weepfnb", "eedgeft", "xbteehy"));
System.out.println(values.get("B1", "RtyName")); // prints the list

我的目标是,我可以拥有的任何数据结构,对于B1,我将获得Rtyname,对于Rtyname,我将获得可能的值列表


共 (2) 个答案

  1. # 1 楼答案

    正如你所要求的:

    您只需定义一个类ABC,在本例中,正如您所建议的那样,它包含两个列表RtyNamertyRate列表:

    public class ABC {
        private List<String> RtyName;
        private List<String> rtyRate;
    
        public ABC(List<String> RtyName, List<String> rtyRate) {
            setRtyNames(RtyName);
            setRtyRates(rtyRate);
        }
    
        public void setRtyNames(List<String> RtyName) {
            this.RtyName = RtyName;
        }
    
        public List<String> getRtyNames() {
            return this.RtyName;
        }
    
        public void setRtyRates(List<String> rtyRate) {
            this.rtyRate = rtyRate;
        }
    
        public List<String> getRtyRates() {
            return this.rtyRate;
        }
    }
    

    该类就绪后,可以将地图定义更改为:

    Map<String, ABC> newdatamap = new HashMap<>();
    

    并像之前一样为其分配新的值,而不是将这些列表嵌套在另一个映射中,并将此映射放入外部映射,而是创建一个新的ABC实例,提供两个列表作为输入参数,并将生成的ABC对象放入映射(正式称为外部映射):

    List<String> RtyName = Arrays.asList("wpn", "wpfnb", "dgeft", "xbthy");
    List<String> rtyRate = Arrays.asList("dd", "ww", "trrty", "httyure");
    newdatamap.put("B1", new ABC(RtyName, rtyRate));
    

    您还可以将这些列表直接指定为输入参数:

    newdatamap.put("B2", new ABC(Arrays.asList("SSSweepn", "wpefSSSnb", "GGeGdgeft", "xbteYYYYhy"), 
                                 Arrays.asList("WWded", "wTeTYw", "YYYYtrerty", "IIIehttyure"));
    

    现在只需调用get(String)即可检索条目,就像您以前所做的那样:

    ABC data = newdatamap.get("B1);
    

    您还可以直接检索其中一个列表,如:

    List<String> RtyNames = newdatamap.get("B1").getRtyNames();
    

    在我看来,这是一种同时管理和阅读更容易的方式。除此之外,您还获得了运行时安全性,因为您不会遇到RtyNamertyRate的最终键入错误

    重新设计更新

    如果RtyName项和rtyRate项总是齐头并进,f.e.wpn是名称,dd是分配的速率,将这些字段组合在一起是有意义的。因此,您可以重构代码,进一步减少一个列表,并引入一个新类:

    public class RtyEntry {
        private String name;
        private String rate;
    
        public RtyEntry(String name, String rate) {
            setName(name);
            setRate(rate);
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return this.name;
        }
    
        public void setRate(String rate) {
            this.rate = rate;
        }
    
        public String getRate() {
            return this.rate;
        }
    }
    

    如果现在将ABC更改为仅包含一个RtyEntry对象列表,如下所示:

    public class ABC {
        private List<RtyEntry> rtyEntries;
    
        public ABC(List<RtyEntry> rtyEntries) {
            this.rtyEntries = rtyEntries;
        }
    
        public ABC() {
            this.rtyEntries = new ArrayList<>();
        }
    
        public void setRtyEntries(List<RtyEntry> rtyEntries) {
            this.rtyEntries = rtyEntries;
        }
    
        public List<RtyEntry> getRtyEntries() {
            return this.rtyEntries;
        }
    
        // convenience methods
    
        public void addRtyEntry(RtyEntry entry) {
            this.rtyEntries.add(entry);
        }
    }
    

    现在,创建将更改为:

    RtyEntry entry1 = new RtyEntry("wpn", "dd");
    List<RtyEntry> entries = Arrays.asList(entry1, ...);
    newdatamap.put("B1", new ABC(entries));
    

    然后,您还可以分配如下新条目:

    newdatamap.get("B1").addRtyEntry(new RtyEntry("wpfnb", "ww"));
    

    检索条目也更改为重构:

    ABC data = newdatamap.get("B1");
    List<RtyEntry> entries = data.getRtyEntries();
    for (RtyEntry entry : entries) {
        System.out.println(entry.getName() + " has a rate of: " + entry.getRate());
    }
    

    当然,您也可以通过以下方式直接检索列表:

    List<RtyEntry> entries = newdatamap.get("B1").getRtyEntries();
    

    和以前一样

  2. # 2 楼答案

    我会这样做:

    Map<Integer, List<String>> dataMap = new HashMap<>();
    dataMap.put("B1".hashCode()+"RtyName".hashCode(), Arrays.asList("weepn", "weepfnb", "eedgeft", "xbteehy"));
    dataMap.put("B1".hashCode()+"rtyRate".hashCode(), Arrays.asList("deed", "ww", "terrty", "hteetyure"));
    dataMap.put("B2".hashCode()+"RtyName".hashCode(), Arrays.asList("SSSweepn", "wpefSSSnb", "GGeGdgeft", "xbteYYYYhy"));
    dataMap.put("B2".hashCode()+"rtyRate".hashCode(), Arrays.asList("WWded", "wTeTYw", "YYYYtrerty", "IIIehttyure"));
    

    这将代表:

    B1, RtyName    > "weepn", "weepfnb", "eedgeft", "xbteehy"
    B1, rtyRate   ->"deed", "ww", "terrty", "hteetyure"
    
    B2, RtyName    > "SSSweepn", "wpefSSSnb", "GGeGdgeft", "xbteYYYYhy"
    B2, rtyRate   ->"WWded", "wTeTYw", "YYYYtrerty", "IIIehttyure"
    

    注意hashCode只是String类中的一个方便函数,可以满足我的需要。如果您愿意,您可以使用自己的滚动键返回String键(或者其他任何键)

    实际上,由于您最初的方法不需要与顺序无关的函数,您甚至可以将String键串联起来用作新键:

    dataMap.put("B1"+"RtyName", Arrays.asList(/*your list here*/));
    

    与第一种方法相比,这种方法不太方便(在编程上也不那么“好”),但仍然比嵌套Map类要好得多。(与hashCode相比,在输出时,按键更容易识别。)

    双向映射

    值作为键

    如果希望每个List值映射到键,或者反过来映射到键,则需要第二个Map

    Map<List<String>, String> valueMap = new HashMap<>(); //New map for value->key 
    for(String key: dataMap.keySet()) //Get all keys
        valueMap.put(dataMap.get(key), key); //Create mapping value->key
    

    每个项目的价值都是一个键

    如果希望values列表中的每个String项都映射到keys或者反过来映射,则需要第二个Map

    Map<String, String> itemMap = new HashMap<>(); //New map for item->key mapping
        for(String key: dataMap.keySet()) //Get all keys and iterate through
            for(String item: dataMap.get(key)) //For each item in your value list
                itemMap.put(item, key); //Create new mapping item->key