代码之家  ›  专栏  ›  技术社区  ›  Gnark

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

  •  1
  • Gnark  · 技术社区  · 16 年前

    我工作了一整天,不知怎么搞不明白这项可能很简单的任务——可能是咖啡不够……

    我有一个 synchronizedList 存储一些对象的位置。那些物体有 field 类似于id。这些对象携带用户及其当前状态的信息(简化)。

    关键是,我只希望每个用户有一个对象。因此,当这个用户的状态改变时,我想删除“old”条目并在 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 回复  |  直到 16 年前
        1
  •  0
  •   extraneon    16 年前

    地图是最简单的,但是集合更好地反映了你的逻辑。如果那样的话,我会给你一套建议。

    根据数据对象的equals和hashcode,有两种使用集合的方法。

    如果您的对象已经使用id对象来确定等于(而hashcode遵守约定),那么您可以使用任何想要的集合,那么hashset可能是最好的。

    如果业务逻辑需要不同的equals,并考虑到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不是问题所建议的int。

        2
  •  3
  •   Brad Cupit Regan    16 年前

    您可以使用hashmap(或者linkedhashmap/treemap,如果顺序很重要的话)和一个id键和一个objects值。使用泛型 HashMap<Object, Objects>();

    那你就可以用

    if (map.containsKey(ID)) {
        map.remove(ID);
    }
    
    map.put(newID, newObject);
    

    或者,您可以继续使用列表,但我们不能在迭代时仅修改集合,因此我们可以使用迭代器移除现有项,然后在循环外部添加新项(现在您确定旧项已消失):

    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);
    
        3
  •  1
  •   Riduidel    16 年前

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

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

        4
  •  1
  •   Andrew Hare    16 年前

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

        5
  •  0
  •   leonbloy    16 年前

    我的第一个选择是 哈希表 ,这将要求您重写 哈希码 和 等于 方法(不要忘记:如果重写其中一个,则始终重写另一个!)因此具有相同id字段的对象被认为是相等的。

    但是,如果不在应用程序的其他部分中进行这种假设,则这可能会破坏某些内容。在这种情况下,您可以选择使用 哈希图 (以id为键)或实现自己的 米哈什特 类(由这样的哈希映射支持)。

    推荐文章