带有对象的 Java 列表 - 如果具有特定属性的对象已存在,则查找并替换(删除)条目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2470329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java List with Objects - find and replace (delete) entry if Object with certain attribute already exists
提问by Gnark
I've been working all day and I somehow can't get this probably easy task figured out - probably a lack of coffee...
我一整天都在工作,但不知怎么的,我无法解决这个可能很容易的任务——可能是因为没有咖啡……
I have a synchronizedListwhere some Objects are being stored. Those objects have a fieldwhich is something like an ID. These objects carry information about a user and his current state (simplified).
我有一个synchronizedList存储一些对象的地方。这些对象有一个field类似于 ID 的东西。这些对象携带有关用户及其当前状态(简化)的信息。
The point is, that I only want one object for each user. So when the state of this user changes, I'd like to remove the "old" entry and store a new one in the List.
关键是,我只想要每个用户一个对象。因此,当该用户的状态发生变化时,我想删除“旧”条目并在List.
protected static class Objects{
...
long time;
Object ID;
...
}
...
...
if (Objects.contains(ID)) {
Objects.remove(ID);
Objects.add(newObject);
} else {
Objects.add(newObject);
}
Obviously this is not the way to go but should illustrate what I'm looking for...
Maybe the data structure is not the best for this purpose but any help is welcome!
显然这不是要走的路,但应该说明我在寻找什么......
也许数据结构不是最好的,但欢迎任何帮助!
编辑:
添加了一些信息...
A
SetSet似乎并不适合我的目的。该ObjectsObjects店内除了它总是在变化的ID一些其他领域。目的是,该列表将以某种方式代表用户的最新活动。我只需要跟踪最后一个状态并只保留描述这种情况的对象。我想我会尝试用 a 重新排列我的代码,
MapMap看看它是否有效......采纳答案by extraneon
A Map is easiest, but a Set reflects your logic better. In that case I'd advice a Set.
Map 是最简单的,但 Set 能更好地反映您的逻辑。在那种情况下,我建议使用 Set。
There are 2 ways to use a set, depending on the equals and hashCode of your data object.
有两种使用集合的方法,具体取决于数据对象的 equals 和 hashCode。
If YourObject already uses the ID object to determine equals (and hashCode obeys the contract) you can use any Set you want, a HashSet is probably best then.
如果 YourObject 已经使用 ID 对象来确定相等(并且 hashCode 遵守合同),您可以使用任何您想要的 Set,那么 HashSet 可能是最好的。
If YourObjects business logic requires a different equals, taking into account multiple fields beside the ID field, then a custom comparator should be used. A TreeSet is a Set which can use such a Comparator.
如果 YourObjects 业务逻辑需要不同的 equals,考虑到 ID 字段旁边的多个字段,则应使用自定义比较器。TreeSet 是一个可以使用这种比较器的集合。
An example:
一个例子:
Comparator<MyObject> comp = new Comparator<MyObject>{
public int compare(MyObject o1, MyObject o2) {
// NOTE this compare is not very good as it obeys the contract but
// is not consistent with equals. compare() == 0 -> equals() != true here
// Better to use some more fields
return o1.getId().hashCode() < o2.getId().hashCode();
}
public boolean equals(Object other) {
return 01.getId().equals(o2.getId());
}
}
Set<MyObject> myObjects = new TreeSet(comp);
EDITI have updated the code above to reflect that id is not an int, as suggested by the question.
编辑我已经更新了上面的代码,以反映 id 不是一个整数,正如问题所建议的那样。
回答by Brad Cupit
You could use a HashMap (or LinkedHashMap/TreeMap if order is important) with a key of ID and a value of Objects. With generics that would be HashMap<Object, Objects>();
您可以使用带有 ID 键和 Objects 值的 HashMap(或 LinkedHashMap/TreeMap,如果顺序很重要)。使用泛型将是HashMap<Object, Objects>();
Then you can use
然后你可以使用
if (map.containsKey(ID)) {
map.remove(ID);
}
map.put(newID, newObject);
Alternatively, you could continue to use a List, but we can't just modify the collection while iterating, so instead we can use an iterator to remove the existing item, and then add the new item outside the loop (now that you're sure the old item is gone):
或者,您可以继续使用 List,但我们不能在迭代时只修改集合,因此我们可以使用迭代器删除现有项目,然后在循环外添加新项目(现在您是确保旧物品不见了):
List<Objects> syncList = ...
for (Iterator<Objects> iterator = syncList.iterator(); iterator.hasNext();) {
Objects current = iterator.next();
if (current.getID().equals(ID)) {
iterator.remove();
}
}
syncList.add(newObject);
回答by Riduidel
回答by Andrew Hare
回答by leonbloy
My first option would be a HashSet, this would require that you override the hashCodeand equalsmethods (don't forget: if you override one, override consistently the other !) so that objects with the same ID field are considered equal.
我的第一个选项是HashSet,这将要求您覆盖hashCode和equals方法(不要忘记:如果您覆盖一个,则始终覆盖另一个!),以便具有相同 ID 字段的对象被视为相等。
But this might break something if this assumption is NOT to be made in other parts of your application. In that case you might opt for using a HashMap(with the ID as key) or implement your own MyHashSetclass (backed by such a HashMap).
但是,如果您的应用程序的其他部分不进行此假设,则这可能会破坏某些内容。在这种情况下,您可能会选择使用HashMap(以 ID 作为键)或实现您自己的MyHashSet类(由此类 HashMap 支持)。

