我不知道你的问题的所有细节,但我的直觉是你可能在这里想太多了。您计划在此数据结构中存储多少对象?如果您要在此处存储大量数据,我建议您使用实际数据库而不是数据结构。您在此处描述的操作类型是关系数据库擅长的经典示例。MySQL和PostgreSQL是大型关系数据库的例子,它们可以在睡眠中做这种事情。如果您想要更轻量级的SQLite ,您可能会感兴趣。
如果您不需要在此数据结构中存储大量数据,我建议您保持简单,并且仅在您确定它的速度不足以满足您的需求时才对其进行优化。作为第一个镜头,我只推荐使用 java 的内置 List 接口来存储您的人员和使用 Map 来存储组。你可以这样做:
// Use a list to keep track of People
List<Person> myPeople = new ArrayList<Person>();
Person steve = new Person("Steve");
myPeople.add(steve);
myPeople.add(new Person("Bob"));
// Use a Map to track Groups
Map<String, List<Person>> groups = new HashMap<String, List<Person>>();
groups.put("Everybody", myPeople);
groups.put("Developers", Arrays.asList(steve));
// Does a group contain everybody?
groups.get("Everybody").containsAll(myPeople); // returns true
groups.get("Developers").containsAll(myPeople); // returns false
这绝对不是可用的最快选项,但如果您没有大量人员需要跟踪,您甚至可能不会注意到任何性能问题。如果您确实有一些特殊情况会导致无法使用常规列表和地图的速度,请发布它们,我们可以根据这些情况提出建议。
编辑:
阅读您的评论后,我似乎在第一次运行时误读了您的问题。看起来您对将组映射到人员不是很感兴趣,而是将人员映射到组。你可能想要的是更像这样的东西:
Map<Person, List<String>> associations = new HashMap<Person, List<String>>();
Person steve = new Person("Steve");
Person ed = new Person("Ed");
associations.put(steve, Arrays.asList("Everybody", "Developers"));
associations.put(ed, Arrays.asList("Everybody"));
// This is the tricky part
boolean sharesGroups = checkForSharedGroups(associations, Arrays.asList(steve, ed));
那么如何实现 checkForSharedGroups 方法呢?在您的情况下,由于围绕此的数字非常低,我只是尝试天真的方法并从那里开始。
public boolean checkForSharedGroups(
Map<Person, List<String>> associations,
List<Person> peopleToCheck){
List<String> groupsThatHaveMembers = new ArrayList<String>();
for(Person p : peopleToCheck){
List<String> groups = associations.get(p);
for(String s : groups){
if(groupsThatHaveMembers.contains(s)){
// We've already seen this group, so we can return
return false;
} else {
groupsThatHaveMembers.add(s);
}
}
}
// If we've made it to this point, nobody shares any groups.
return true;
}
这种方法在大型数据集上可能没有很好的性能,但是很容易理解。因为它被封装在它自己的方法中,所以如果你需要更好的性能,它也应该很容易更新。如果您确实需要提高性能,我会考虑覆盖 Person 的 equals 方法,这将使关联映射中的查找更快。从那里您还可以查看自定义类型而不是组的 String,也可以使用覆盖的 equals 方法。这将大大加快上面使用的 contains 方法。
我不太关心性能的原因是,就算法而言,您提到的数字并没有那么大。因为这个方法一找到两个匹配的组就会返回,在最坏的情况下,您将调用 ArrayList.contains 的次数等于存在的组数。在最好的情况下,它只需要被调用两次。只有当您非常非常频繁地调用 checkForSharedGroups 时,性能才可能成为问题,在这种情况下,您最好找到一种不那么频繁地调用它的方法,而不是优化方法本身。