什么Java数据结构/解决方案最适合这些要求?

时间:2009-04-20 02:14:46

标签: java data-structures collections concurrency

我需要一个满足这些要求的java数据结构/解决方案。什么最适合这些?

1)必须保留对象的插入顺序

2)对象必须是唯一的(这些是由UUID唯一标识的数据库对象)。

3)如果添加了具有相同ID的较新对象,则应覆盖/删除旧版本的对象

4)许多线程都应该可以访问解决方案。

5)当读取/使用添加到Structure的第一个对象时,应该从数据结构中删除它

5 个答案:

答案 0 :(得分:10)

这里有几种可能性。最简单的可能是从LinkedHashSet开始。这将为您提供所需的唯一性和可预测的排序。然后,您可以包装结果集以使其成为线程安全的:

Set<T> s = Collections.synchronizedSet(new LinkedHashSet<T>(...));

注意:由于Set没有真正定义从中检索项目的方法,因此您的代码必须手动调用Set.remove(Object)。

或者,你可以包装一个LinkedHashMap,它确实为你需要的delete-on-read语义提供了一个钩子:

class DeleteOnReadMap<K, V> implements Map<K, V> {

    private Map<K, V> m = new LinkedHashMap<K, V>();

    // implement Map "read" methods Map with delete-on-read semantics
    public V get(K key) {
        // ...
    }
    // (other read methods here)

    // implement remaining Map methods by forwarding to inner Map
    public V put(K key, V value) {
        return m.put(key, value);
    }
    // (remaining Map methods here)
}

最后,包装自定义Map的实例以使其成为线程安全的:

Map<K, V> m = Collections.synchronizedMap(new DeleteOnReadMap<K, V>(...));

答案 1 :(得分:1)

我的想法如下:

 Collections.synchronizedMap(new LinkedHashMap<K, V>());

我认为除了要求5之外,它会处理所有事情,但您可以使用remove()方法代替get()来完成此操作。

这不会像ConcurrentMap那样有效 - 同步会在每次访问时锁定整个映射,但我认为ConncurrentMap实现只能使用读写锁和选择性锁定地图的一部分,允许多个非冲突访问同时进行。如果您愿意,可以通过编写自己的一些现有Map实现的子类来获得更好的性能。

答案 2 :(得分:1)

  

1)对象的插入顺序必须是   保持

这是任何“普通”数据结构 - 数组,arrayList,树。因此,请避免自我平衡或自我排序数据结构:堆,哈希表或移动到前面的树(例如,splay树)。然后再次,可以使用其中一个结构,但那么你必须跟踪每个节点的插入顺序。

  

2)对象必须是唯一的(这些是   唯一的数据库对象   由UUID确定。

保留与每个对象关联的唯一标识符。如果这是一个C程序,那么指向该节点的指针是唯一的(我想这也适用于Java。)如果节点的指针不足以维持“唯一性”,那么你需要为每个节点添加一个字段你保证拥有独特的价值。

  

3)如果是具有相同ID的较新对象   添加,旧版本的   对象应该被覆盖/删除

您想在哪里放置节点?您想要替换现有节点吗?或者您要删除旧节点,然后将新节点添加到最后?这很重要,因为它与您的要求#1有关,其中必须保留插入顺序。

  

4)解决方案应该是可访问的   由许多线程。

我能想到的唯一方法就是实现某种锁定。 Java允许您在synchronized块中包含结构和代码。

  

5)当第一个对象添加到   读取/使用结构,应该是   从数据结构中删除

有点像“出队”行动。

看起来像ArrayList是一个非常好的选择:仅仅因为#5。唯一的问题是搜索是线性的。但是如果你的数据量相对较少,那就不是那么大的问题了。

否则,像其他人一样说:HashMap甚至某种树都可以工作 - 但这取决于访问的频率。 (例如,如果最有可能访问“最新”元素,我将使用线性结构。但如果访问将是“随机”元素,我将使用HashMap或树。)

答案 3 :(得分:1)

关于LinkedHashSet的解决方案将是一个很好的起点。

但是,您必须覆盖要放入集合中的对象的equals和hashcode方法,以满足您的要求编号3.

答案 4 :(得分:0)

听起来你必须创建自己的数据结构,但这听起来像一个非常简单的类分配。

基本上你从数组或堆栈开始,但是你必须扩展它以完成剩余的功能。

您可以根据需要查看“包含”方法。