【问题标题】:How to maintain an Ordered Linked List and add, remove elements in java如何维护有序链表并在java中添加、删除元素
【发布时间】:2014-08-08 00:57:52
【问题描述】:

我想维护一个名为“ClientStatus”的对象列表,其中只包含客户端标识 (id) 和一些时间字段,即与该客户端相关的时间字段。此列表应根据此时间字段按升序排序。我要支持的操作是:

* peek and remove an entry from the beginning 
* Search the list for an entry and if found, remove it
* Add an entry to this list

我希望每个新条目都有时间 >= 列表中的最后一个条目,但有可能出现竞争条件,我可能会得到乱序值。所以我认为从最后迭代列表将是最省时的解决方案。

这些是我使用的 DS:

  • LinkedList 和 ListIterator 作为 ListIterator 允许您从末尾迭代元素并在迭代时添加新条目。但是代码看起来很乱:

    假设我的列表有值:2 3 6 7 9,我想添加 5

    ListIterator<Integer> it = list.listIterator(list.size());
    
    while (it.hasPrevious()) {
        if (it.previous().intValue() <= 5) {    
            it.next();
            break;
        }
    }
    

    有没有更好的方法来做到这一点?

  • 我也尝试过使用 LinkedList 和 Dequeue,但降序迭代器不允许您添加/删除条目。我试图计算索引,但随后 set(index, value) 替换了现有条目。如何在列表中插入条目?

====================== 修订版 2 ======================= =====

根据我决定使用 SortedSet 的共识,如果我编写的代码可以在 Comparator 和 equals 之间的一致性方面进行技术性审查,我将不胜感激。

private static class ClientStatus {
    public long id;
    public long time;

    public ClientStatus(final long id, final long time) {
        this.id = id;
        this.time = time;
    }

    @Override
    public boolean equals(final Object o) {
        if ((o == null) || (getClass() != o.getClass())) {
            return false;
        }
        if (this == o) {
            return true;
        }
        ClientStatus obj = (ClientStatus) o;
        return this.id == obj.id;
    }
}

public static void main(String[] args) {

    SortedSet<ClientStatus> active_client_set = new TreeSet<ClientStatus>(
            new Comparator<ClientStatus>() {
                @Override
                public int compare(final ClientStatus o1, final ClientStatus o2) {
                    if (o1.getClass() != o2.getClass()) {
                        return -1;
                    }

                    if (o1 == o2 || o1.id == o2.id) {
                        return 0;
                    }
                    return (o1.time - o2.time) < 0 ? -1 : +1;
                }
            }
    );
}

我在比较 id 的唯一一个客户端 id 列表中不能有多个条目,但是两个不同的客户端可以有相同的时间值。此代码似乎不起作用,添加工作正常但如果我无法删除仅基于 clientid 的条目。

【问题讨论】:

  • 是否需要允许重复条目?
  • 我认为SortedSet 可能是要走的路。但是,如果您想使用LinkedList,通过计算索引,您似乎走在了正确的轨道上,但使用add 方法将在列表中插入一个新条目。请参阅LinkedList javadoc

标签: java linked-list iterator listiterator


【解决方案1】:

我认为您要查找的类型是SortedSet,可以由TreeSet 实现。

有序集合通过使用它们的compare(...) 实现来保持集合中的所有条目排序。

集合中的所有元素都必须实现Comparator&lt;T&gt; 接口,SortedSet 才能正常工作。

您可能更喜欢使用SortedMap,它的工作方式类似。您可以将客户端 id 设置为 value,将 time 字段设置为 key,并且 map 将使用 time 字段比较保持排序。

您还谈到了比赛条件。使用 TreeMap 的 javadoc 讨论了这一点,并提到必须使用 Collections.synchronizedSortedMap(...) 在外部同步地图。

我还没有尝试过同步实现,所以我不能补充太多。

查看文档了解更多信息:

http://docs.oracle.com/javase/7/docs/api/java/util/SortedSet.html http://docs.oracle.com/javase/7/docs/api/java/util/SortedMap.html

【讨论】:

    【解决方案2】:

    我希望每个新条目都有时间 >= 列表中的最后一个条目 但是我可能会退出比赛状态 订单值。所以我认为从最后迭代列表 将是最省时的解决方案。

    如果您有可能并发访问,则必须同步 LinkedList 的迭代和变异。您不会只是让项目乱序,最好的情况是迭代导致 ConcurrentModificationException,最坏的情况是不确定的数据丢失。

    【讨论】:

      猜你喜欢
      • 2011-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      相关资源
      最近更新 更多