问题描述
我希望能够查询每个没有值的键。 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)。