我建议您制作一个将单个键映射到其整个组的映射。
所以,而不是你写的,这个:
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)。