【问题标题】:Java multikey map with no value没有值的 Java 多键映射
【发布时间】:2021-05-03 11:51:38
【问题描述】:

我希望能够查询没有值的每个键。 A1...n , B1...n 是字符串。 我有一组字符串,我需要将它们添加到结构中,以便能够查询每个字符串并获取其组字符串。

例如:{A1, A2, A3} , {B1,B2,B3, B4....., Bn}

map.get(A1) --> return {A2,A3}
map.get(A2) --> return {A1,A3}
map.get(A3) --> return {A1,A2}
map.get(B1) --> return {B2,B3, B4...Bn}
map.get(B2) --> return {B1,B3, B4 ..Bn}
map.get(B3) --> return {B1,B2, B4...Bn}

等等……

我应该使用哪种数据结构有什么建议吗?

【问题讨论】:

  • 我假设blah.get(B1) 也应该返回B4...Bn?
  • A1、A2 和 A3 都相等吗?如果是这样,你如何区分这三个?如果不是,您如何确定它们是匹配集?
  • 这个问题不清楚。 A1和B1有哪些类型?如果它们不同,这从一开始就不起作用(因为这意味着 blah 具有异构键类型,不是一个好的开始)。在您的示例中没有 get 调用返回“无价值”。
  • @rzwitserloot A1...n , B1...n 是字符串。我有一组字符串,我需要将其添加到结构中,以便能够查询每个字符串并获取其组字符串。
  • 我还不太明白您要做什么。字符串“A1”...“An”、“B1”...“Bn”与您要添加到某个结构中的字符串集之间有什么关系?而且这个结构还没有选择(但是您在示例中将其称为 map),对吗?您还提到“组字符串”,这些是什么?

标签: java data-structures multikey


【解决方案1】:

我建议您制作一个映射,将单个键映射到其整个组

所以,不是你写的,而是:

A1 -> {A1, A2, A3}

如果您随后有诸如“列出组成员,但不列出自己”之类的操作,只需在该点编写该逻辑(循环遍历组并跳过自己/使用 stream().filter()操作)。

这样可以节省大量内存 - 每个“组”都可以是同一个对象。这也意味着如果你有可变组,你可以只对组进行操作(不过,你必须小心地同时更新地图):

String[][] input = {
   {"A1", "A2", "A3"},
   {"B1", "B2"}};

public Map<String, SortedSet<String>> makeGroupsData() {
    var out = new HashMap<String, List<String>>();
    for (String[] group : input) {
        SortedSet<String> groupSet = new TreeSet<>(Arrays.asList(group));
        for (String g : group) out.put(g, groupSet);
    }

    return out;
}

// and then for operations:

/** Returns a list of all <em>other</em> members of the group */
public SortedSet<String> getGroupMembers(String key) {
    var group = groups.get(key);
    if (group == null) throw new IllegalArgumentException("unknown: " + key);
    var out = new TreeSet<String>(group);
    out.remove(key);
    return out;
}

public int getGroupSize(String key) {
    Set<String> group = groups.get(key);
    return group == null ? 0 : group.size();
}

你明白了 - 例如,我不确定 SortedSet 是否适合你。关键是,这意味着一个组只有 1 个对象(一个 TreeSet),而地图只是将每个单独的成员链接到同一个组对象。

注意:大警告:这假定任何给定的字符串不能是多个组的成员,并且此代码不会检查它。您可能想要(.put 方法返回之前的映射,因此您所要做的就是检查 .put 方法是否返回非空值;如果是,则抛出 IllegalArgumentException)。

【讨论】:

    猜你喜欢
    • 2011-10-09
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2015-08-22
    • 2010-12-13
    • 2015-08-12
    相关资源
    最近更新 更多