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

时间:2010-03-18 14:00:47

标签: java list collections object contains

我一整天都在工作,我不知道这个可能很容易弄清楚的事情 - 可能是缺少咖啡......

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

关键是,我只想为每个用户提供一个对象。因此,当此用户的状态发生变化时,我想删除“旧”条目并在List中存储新条目。

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

...

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

显然这不是要走的路,但应该说明我正在寻找的东西......
也许数据结构不是最好的,但欢迎任何帮助!

<小时/> 编辑:
添加了一些信息......
Set似乎并不符合我的目的。 Objects存储ID以外的其他一些字段,这些字段一直在变化。目的是,列表将以某种方式表示用户的最新活动。我只需跟踪最后一个状态,只保留描述这种情况的对象 我想我会尝试用Map重新安排我的代码,看看是否有效......

5 个答案:

答案 0 :(得分:3)

您可以使用HashMap(或者如果顺序很重要的话,使用LinkedHashMap / TreeMap),ID为ID,对象值为。使用泛型HashMap<Object, Objects>();

然后你可以使用

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

答案 1 :(得分:1)

你不能使用Set只存储第一个?

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

地图是最简单的,但是设置会更好地反映您的逻辑。在那种情况下,我会建议一套。

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

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

如果YourObjects业务逻辑需要不同的等于,考虑ID字段旁边的多个字段,则应使用自定义比较器。 TreeSet是一个可以使用这种比较器的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,正如问题所示。

答案 4 :(得分:0)

我的第一个选项是 HashSet ,这需要您覆盖 hashCode equals 方法(不要忘记:如果你覆盖一个,一直覆盖另一个!),以便具有相同ID字段的对象被认为是相等的。

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