使用java

时间:2015-06-13 01:22:20

标签: java data-structures

我有一张如下图所示的地图,其中有一个键,值为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的类,所以它就像

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

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

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

所以在上面的结构中,复杂性会很低,因为在B1结束时我必须搜索关键字,即RtyName和付款人姓名,我必须搜索“wpn”,“wpfnb”,“dgeft”的值“,”xbthy“

请告知whheteher地图将是最好的还是有任何其他更好的数据结构也可以获得此。

我想到的一个数据结构是Guava的表

  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 个答案:

答案 0 :(得分:1)

我会这样做:

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

这比第一种方法稍微不方便(而不是#34;良好&#34;编程),但仍然比嵌套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

值中的每个项目作为键

如果您希望String列表中的每个values项目都映射到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

答案 1 :(得分:0)

正如你所要求的那样:

在这种情况下,您只需定义一个类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();
和以前一样。