简体   繁体   English

如何维护有序链接列表以及添加,删除Java中的元素

[英]How to maintain an Ordered Linked List and add, remove elements in java

I want to maintain a list of objects called 'ClientStatus' that contain nothing but client identification (id) and some time field ie related to this client. 我想维护一个名为“ ClientStatus”的对象列表,其中只包含客户端标识(id)和一些与该客户端相关的时间字段。 This list should be sorted in terms of this time field in increasing order. 该列表应根据此时间字段以升序排序。 The operations I want to support are : 我要支持的操作是:

* 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

I expect every new entry to have time >= the last entry in the list but there is a possibility of race condition where I might get out of order values. 我希望每个新条目的时间> ==列表中的最后一个条目,但是有可能出现竞争状况,我可能会失序。 SO I figured that iterating over the list from the end will be the most time-efficient solution. 因此,我认为从头开始遍历列表将是最省时的解决方案。

These are the DS I used: 这些是我使用的DS:

  • LinkedList and ListIterator as ListIterator allows you to iterate over the elements from the end and add new entries while iteration. LinkedList和ListIterator作为ListIterator允许您从头开始遍历元素,并在迭代时添加新条目。 But the code looks messy: 但是代码看起来很混乱:

    Say my list has values: 2 3 6 7 9 and I want to add 5 说我的清单中有值:2 3 6 7 9我想加5

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

    Is there a better way to do this? 有一个更好的方法吗?

  • I also tried using LinkedList and Dequeue but the descending iterator doesn't let you add/remove entries. 我也尝试使用LinkedList和Dequeue,但递减的迭代器不允许您添加/删除条目。 I tried to count indices but then set(index, value) replaces existing entry. 我试图计算索引,但是set(index,value)替换了现有条目。 How do I insert an entry in the list? 如何在列表中插入一个条目?

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

As per the consensus I decided to use a SortedSet, I'll appreciate if the code I wrote can be reviewed for technicalities in consistency between Comparator and equals. 按照我决定使用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;
                }
            }
    );
}

I'm comparing the id's only one client id can't have multiple entries in the list, but two different clients can have the same time value. 我正在比较ID的唯一一个客户端ID在列表中不能有多个条目,但是两个不同的客户端可以具有相同的时间值。 This code doesn't seem to work, addition works just fine but if I'm unable to remove an entry based on clientid only. 这段代码似乎不起作用,添加工作也很好,但是如果我无法仅基于clientid删除条目。

I think the type you are looking for is a SortedSet which can be implemented by TreeSet . 我认为您正在寻找的类型是可以由TreeSet实现的SortedSet

The sorted set keeps all the entries in the set sorted by using their compare(...) implementation. 排序后的集合使用它们的compare(...)实现对集合中的所有条目进行排序。

All the elements in the set must implement the Comparator<T> interface in order for the SortedSet to work properly. 集合中的所有元素都必须实现Comparator<T>接口,以使SortedSet正常工作。

You might prefer to use SortedMap which works in a similar way. 您可能希望使用以类似方式工作的SortedMap You can set the client id as the value and the time field as the key, and the map will keep the sorting using the time field comparison. 您可以将客户端ID设置为值,将时间字段设置为键,地图将使用时间字段比较来保持排序。

You were also talking about race conditions. 您也在谈论比赛条件。 The javadoc for using TreeMap discusses this and mentioning that the map must be synchronized externally by using Collections.synchronizedSortedMap(...) . 使用TreeMap的Javadoc对此进行了讨论,并提到必须通过使用Collections.synchronizedSortedMap(...)在外部对地图进行同步。

I haven't tried the synchronized implementation so I can't add much about it. 我还没有尝试过同步实现,所以不能对此做太多介绍。

Check out the docs for more info: 查看文档以获取更多信息:

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

I expect every new entry to have time >= the last entry in the list but there is a possibility of race condition where I might get out of order values. 我希望每个新条目的时间> ==列表中的最后一个条目,但是有可能出现竞争状况,我可能会失序。 SO I figured that iterating over the list from the end will be the most time-efficient solution. 因此,我认为从头开始遍历列表将是最省时的解决方案。

If you have the possibility of concurrent access, you MUST synchronize iteration and mutation of a LinkedList. 如果可以进行并发访问,则必须同步LinkedList的迭代和突变。 You will not just get items out of order, your best case scenario is that the iteration causes a ConcurrentModificationException, the worst case is the indeterminate loss of data. 您不仅会导致项目混乱,最好的情况是迭代导致ConcurrentModificationException,最坏的情况是不确定的数据丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM