1

我已经工作了一整天,但不知怎的,我无法弄清楚这个可能很容易的任务——可能是因为缺少咖啡……

我有一个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);
        }

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


编辑:
添加了一些信息......
ASet似乎并不真正符合我的目的。存储除了ID之外的Objects一些其他字段,这些字段一直在变化。目的是,该列表将以某种方式代表用户的最新活动。我只需要跟踪最后一个状态并只保留描述这种情况的那个对象。
我想我会尝试用 a 重新安排我的代码,Map看看是否可行......

4

5 回答 5

3

您可以使用带有 ID 键和 Objects 值的 HashMap(或 LinkedHashMap/TreeMap,如果顺序很重要)。使用泛型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);
于 2010-03-18T15:03:18.467 回答
1

而且您不能使用Set只存储第一个?

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

于 2010-03-18T14:03:25.903 回答
1

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

于 2010-03-18T14:03:34.630 回答
0

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

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

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

如果 YourObjects 业务逻辑需要不同的等号,考虑到 ID 字段旁边的多个字段,则应使用自定义比较器。TreeSet 是一个可以使用这种比较器的集合。

一个例子:

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 不是整数,正如问题所建议的那样。

于 2010-03-18T14:03:31.207 回答
0

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

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

于 2010-03-18T14:42:29.107 回答