如何将两个 HashSet 与部分相等的对象合并?
How to merge to HashSets with partially equal Objects?
我有一个 ArrayList data
包含类型为 Person
的对象,它每 n 秒更新一次并且具有现有数据的总量。
为了在 table 中显示此数据,我曾经 clear()
一个 ObservableList 并使用 addAll(data)
来避免 GUI 故障。
我想使用 HashSet 作为 Observable Collection,我想知道是否有一种有效的方法从 HashSet 更新对象,如果它只是部分相等的话。
代码:
class Person {
int id;
String name;
int visits; //this value can be different
@Override
int hashCode() {
//...
}
@Override
boolean equals() {
//...
}
}
class Main {
static void main(String[] args) {
List<Person> data = new ArrayList<>();
data.add(new Person(1, Max, 4);
data.add(new Person(2, Richard, 7);
data.add(new Person(3, Tom, 4);
Set<Person> set = new HashSet<>();
set.addAll(data);
// new Data incoming
// could be the same Person (all 3 variables same)
// could be existing Person but with changed variables (id stays the same)
// could be completely new Person (new id)
}
}
期望输出:
如果添加新数据时使用现有的 Person 但变量不同
new Person(1, Max, 50);
该位置的索引应删除 Max 并添加新的 Max 50 次访问(可能在同一位置)
或者最好将变量访问次数更改为 50。
如果所有数据都相同(使用 equals() 和 hashCode() 检查):不应添加或删除任何内容
如果 HashSet 中没有新的 Person(具有新 ID),则应添加它
这是如何实现的?
我尝试使用 2 个 for 循环(这很耗时)并覆盖哈希集,但我不确定该方法。
不存在部分相等这回事。您的方法 equals()
return true
或 false
。在您的情况下,您所说的平等仅由人的身份决定。 IE。如果你添加一个具有相同 id 的人,其他都不重要,即使 visits
值不同,两个 Person 实例也会被判断为相等。因此,如果您将 Person 实例存储在集合中并添加一个 id 为 1 的 Person - 如果该集合已经包含一个 id 为 1 的 Person,则旧的将被新的替换。还要记住 Set
没有顺序。如果您想保留订单,请使用 SortedSet
或 List
。但是如果你使用List
,你将不得不编写代码来确保你自己不允许重复
使用 Map
,而不是 Set
。
List<Person> data = new ArrayList<>();
data.add(new Person(1, Max, 4);
data.add(new Person(2, Richard, 7);
data.add(new Person(3, Tom, 4);
Map<Integer, Person> map = new HashMap<>();
data.forEach(person -> map.put(person.getId(), person));
// new Data incoming
// could be the same Person (all 3 variables same)
// could be existing Person but with changed variables (id stays the same)
// could be completely new Person (new id)
Person newPerson = ...;
map.put(newPerson.getId(), newPerson);
如果你想按 ID 排序,你可以使用 TreeMap
,如果你想按进入顺序排序,你可以使用 LinkedHashMap
。
我有一个 ArrayList data
包含类型为 Person
的对象,它每 n 秒更新一次并且具有现有数据的总量。
为了在 table 中显示此数据,我曾经 clear()
一个 ObservableList 并使用 addAll(data)
来避免 GUI 故障。
我想使用 HashSet 作为 Observable Collection,我想知道是否有一种有效的方法从 HashSet 更新对象,如果它只是部分相等的话。
代码:
class Person {
int id;
String name;
int visits; //this value can be different
@Override
int hashCode() {
//...
}
@Override
boolean equals() {
//...
}
}
class Main {
static void main(String[] args) {
List<Person> data = new ArrayList<>();
data.add(new Person(1, Max, 4);
data.add(new Person(2, Richard, 7);
data.add(new Person(3, Tom, 4);
Set<Person> set = new HashSet<>();
set.addAll(data);
// new Data incoming
// could be the same Person (all 3 variables same)
// could be existing Person but with changed variables (id stays the same)
// could be completely new Person (new id)
}
}
期望输出:
如果添加新数据时使用现有的 Person 但变量不同
new Person(1, Max, 50);
该位置的索引应删除 Max 并添加新的 Max 50 次访问(可能在同一位置)
或者最好将变量访问次数更改为 50。
如果所有数据都相同(使用 equals() 和 hashCode() 检查):不应添加或删除任何内容
如果 HashSet 中没有新的 Person(具有新 ID),则应添加它
这是如何实现的? 我尝试使用 2 个 for 循环(这很耗时)并覆盖哈希集,但我不确定该方法。
不存在部分相等这回事。您的方法 equals()
return true
或 false
。在您的情况下,您所说的平等仅由人的身份决定。 IE。如果你添加一个具有相同 id 的人,其他都不重要,即使 visits
值不同,两个 Person 实例也会被判断为相等。因此,如果您将 Person 实例存储在集合中并添加一个 id 为 1 的 Person - 如果该集合已经包含一个 id 为 1 的 Person,则旧的将被新的替换。还要记住 Set
没有顺序。如果您想保留订单,请使用 SortedSet
或 List
。但是如果你使用List
,你将不得不编写代码来确保你自己不允许重复
使用 Map
,而不是 Set
。
List<Person> data = new ArrayList<>();
data.add(new Person(1, Max, 4);
data.add(new Person(2, Richard, 7);
data.add(new Person(3, Tom, 4);
Map<Integer, Person> map = new HashMap<>();
data.forEach(person -> map.put(person.getId(), person));
// new Data incoming
// could be the same Person (all 3 variables same)
// could be existing Person but with changed variables (id stays the same)
// could be completely new Person (new id)
Person newPerson = ...;
map.put(newPerson.getId(), newPerson);
如果你想按 ID 排序,你可以使用 TreeMap
,如果你想按进入顺序排序,你可以使用 LinkedHashMap
。