Java 对象列表 - 如果具有特定属性的对象已存在,则查找并替换(删除)条目

发布于 2024-08-26 09:03:38 字数 1118 浏览 7 评论 0原文

我已经工作了一整天,但不知怎的,我无法解决这个可能很简单的任务 - 可能是缺少咖啡......

我有一个 synchronizedList ,其中存储了一些对象。这些对象有一个类似于 ID 的字段。这些对象携带有关用户及其当前状态(简化)的信息。

重点是,我只想要每个用户一个对象。因此,当该用户的状态发生变化时,我想删除“旧”条目并将新条目存储在 List 中。

protected static class Objects{
    ...
    long time;
    Object ID;
    ... 
    }

...

if (Objects.contains(ID)) {
            Objects.remove(ID);
            Objects.add(newObject);
        } else {
            Objects.add(newObject);
        }

显然这不是正确的方法但应该说明我正在寻找什么......
也许数据结构不是最适合此目的的,但欢迎任何帮助!


EDIT:
Added some information...
A Set does not really seem to fit my purpose. The Objects store some other fields besides the ID which change all the time. The purpose is, that the list will somehow represent the latest activities of a user. I only need to track the last state and only keep that object which describes this situation.
I think I will try out re-arranging my code with a Map and see if that works...

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 synchronizedList where some Objects are being stored. Those objects have a field which is something like an ID. These objects carry information about a user and his current state (simplified).

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.

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!


EDIT:
Added some information...
A Set does not really seem to fit my purpose. The Objects store some other fields besides the ID which change all the time. The purpose is, that the list will somehow represent the latest activities of a user. I only need to track the last state and only keep that object which describes this situation.
I think I will try out re-arranging my code with a Map and see if that works...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

戏蝶舞 2024-09-02 09:03:38

您可以使用带有 ID 键和对象值的 HashMap(如果顺序很重要,则使用 LinkedHashMap/TreeMap)。如果泛型是 HashMap();

那么你可以使用

if (map.containsKey(ID)) {
    map.remove(ID);
}

map.put(newID, newObject);

或者,你可以继续使用 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);

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>();

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<Objects> syncList = ...

for (Iterator<Objects> iterator = syncList.iterator(); iterator.hasNext();) {
    Objects current = iterator.next();

    if (current.getID().equals(ID)) {
        iterator.remove();
    }
}

syncList.add(newObject);
蔚蓝源自深海 2024-09-02 09:03:38

并且您不能使用 Set 仅存储第一个?

因为它基本上正是您所需要的。

And you can't use a Set to have only the first one stored ?

because it basically is precisely what you require.

可可 2024-09-02 09:03:38

您可以使用 HashSet来存储对象,然后重写 HashSet 将包含的类中的 hashCode 方法,以返回标识字段的哈希码。

You could use a HashSet to store the objects and then override the hashCode method in the class that the HashSet will contain to return the hashcode of your identifying field.

风吹过旳痕迹 2024-09-02 09:03:38

映射是最简单的,但集合可以更好地反映您的逻辑。在这种情况下我会建议一套。

有两种使用集合的方法,具体取决于数据对象的 equals 和 hashCode。

如果 YourObject 已经使用 ID 对象来确定 equals(并且 hashCode 遵守约定),您可以使用任何您想要的 Set,那么 HashSet 可能是最好的。

如果 YourObjects 业务逻辑需要不同的 equals,并考虑到 ID 字段旁边的多个字段,则应使用自定义比较器。 TreeSet 是一个可以使用此类 Comparator 的 Set。

示例:

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);

编辑
我已经更新了上面的代码以反映 id 不是 int,正如问题所建议的那样。

A Map is easiest, but a Set reflects your logic better. In that case I'd advice a Set.

There are 2 ways to use a set, depending on the equals and hashCode of your data object.

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.

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.

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);

EDIT
I have updated the code above to reflect that id is not an int, as suggested by the question.

一抹微笑 2024-09-02 09:03:38

我的第一个选择是 HashSet,这需要您重写 hashCodeequals 方法(不要忘记:如果您重写一个,一致地覆盖另一个!),以便具有相同 ID 字段的对象被认为是相等的。

但是,如果不在应用程序的其他部分进行此假设,则可能会破坏某些内容。在这种情况下,您可能会选择使用 HashMap (以 ID 作为键)或实现您自己的 MyHashSet 类(由这样的 HashMap 支持) )。

My first option would be a HashSet, this would require that you override the hashCode and equals methods (don't forget: if you override one, override consistently the other !) so that objects with the same ID field are considered equal.

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 MyHashSet class (backed by such a HashMap).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文