我在评论中的意思的粗略概述:
人
class Person {
long id;
Person(long id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
// Compare by id
}
@Override
public int hashCode() {
// Hash by id
}
}
连接
class Connection {
Person person1;
Person person2;
Connection(Person person1, Person person2) {
if (person1.equals(person2)) throw new IllegalArgumentException("Cannot connect a person to itself");
if (person1.id < person2.id) {
this.person1 = person1;
this.person2 = person2;
} else {
// The person1 field should contain the person with the smaller id
this.person1 = person2;
this.person2 = person1;
}
}
@Override
public boolean equals(Object o) {
// Compare person1 and person2
}
@Override
public int hashCode() {
// Hash person1 and person2
}
}
连接管理器
class ConnectionManager {
Set<Connection> connections = new HashSet<Connection>();
Map<Person, Set<Person>> adjacency = new HashMap<Person, Set<Person>>();
public void connect(Person p1, Person p2) {
Connection connection = new Connection(p1, p2);
if (connections.add(connection)) {
getAdjacency(p1).add(p2);
getAdjacency(p2).add(p1);
} else {
throw new RuntimeException(String.format("Persons %d and %d are already connected", p1.id, p2.id));
}
}
private Set<Person> getAdjacency(Person person) {
Set<Person> result = adjacency.get(person);
if (result == null) {
adjacency.put(person, result = new HashSet<Person>());
}
return result;
}
public void disconnect(Person p1, Person p2) {
if (connections.remove(new Connection(p1, p2))) {
getAdjacency(p1).remove(p2);
getAdjacency(p2).remove(p1);
} else {
throw new RuntimeException(String.format("No connection between persons %d and %d exists", p1.id, p2.id));
}
}
public Collection<Map.Entry<Person, Set<Person>>> getMostConnected() {
int maxConnections = 0;
List<Map.Entry<Person, Set<Person>>> result = new ArrayList<Map.Entry<Person, Set<Person>>>();
// return all the entries with the maximum size;
for (Map.Entry<Person, Set<Person>> entry : adjacency.entrySet()) {
int connections = entry.getValue().size();
if (connections > maxConnections) {
result.clear();
maxConnections=connections;
}
if (connections == maxConnections) {
result.add(entry);
}
}
return result;
}
public Set<Person> getConnections(Person person) {
return new HashSet(getAdjacency(person));
}
}
为简洁起见,省略了 Getters/setters 和 equals()/hashCode() 实现 - 无论 IDE 为后者生成什么都可以。
这段代码本质上是一个矩阵,用邻接表表示。唯一不是 O(1) 的部分是搜索具有最多联系的人的部分,即 O(n)。
您可以通过使用PriorityQueue 来降低性能损失,该PriorityQueue 保存存储在adjacency 映射中的Set<Person> 对象,并将设置大小作为“优先级”。每当这样的集合即将被触及时,将其从队列中移除、更改并再次插入。 (但我的直觉是,这只会让连接和断开连接的人变慢,从而让连接最多的人更快。)
免责声明:以上代码完全未经测试,只是为了让您了解可以尝试的内容。