没有值的 Java 多键映射

问题描述

我希望能够查询每个没有值的键。 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,B4...Bn}
map.get(B2) --> return {B1,B4 ..Bn}
map.get(B3) --> return {B1,B4...Bn}

等等...

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

解决方法

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

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

A1 -> {A1,A2,A3}

如果你有一个操作,比如“列出组的成员,但不要列出你自己”,只需在那时编写该逻辑(循环遍历组并跳过你自己/使用流()。过滤器()操作来做到这一点)。

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

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)。