As the title states, I am looking for a java collection keeping only the N last objects inserted into the collection. This FIFO collection does not need to implement random access or support changing N.
All collections I can find are either blocking (LinkedBlockingQueue) or of unlimited size (ArrayDeque). I found org.eclipse.jetty.util.ArrayQueue but as you could guess this brings quite an unwanted dependency on my project and also is very complicated since it support changing N so its not what I need.
Do you know if there is a way to have that with a quite common java library or do I have to write it myself?
Check out Apache Commons CircularFifoBuffer
CircularFifoBuffer is a first in first out buffer with a fixed size
that replaces its oldest element if full.
The removal order of a CircularFifoBuffer is based on the insertion
order; elements are removed in the same order in which they were
added. The iteration order is the same as the removal order.
I would just write a wrapper class which contains a private Queue or Deque instance and a public insert method which behaves as you need if the queue is already full when the client tries to insert an extra member. The size could be passed in via the constructor, and any methods belonging to Queue or Deque which you need available but which already behave as you need you could simply forward to the private instance.
After Guava 15.0 there's EvictingQueue which come with a fixed size that replaces its oldest element if full.
Related
I am currently studying about Algorithms & Data Structures and while I was reading over the Book of Algorithms 4th edition, I discovered the Bag data-structure together with the Stack and Queue.
After reading the the explanation of it, it is still unclear to me why would I prefer using a Bag (which has no remove() method) over other data-structures such as Stack, Queue, LinkedList or a Set?
As far as I can understand from the Book, the implementation of a Bag, is the same as for a Stack, just replacing the name of push() to add() and remove the pop() method.
So the idea of a Bag is basically having the ability to collect items and then iterate through the collected items, check if a bag is empty and find the number of items in it.
But under which circumstances I would better using a Bag over one of the mentioned above Collections? And why a Bag doesn't have a remove() method basically? is there a specific reason for it?
Thanks in advance.
Stack is ADT of the collection of elements with specific remove order = LIFO (last-in-first-out), allows duplicates,
Queue is ADT of the collection of elements with specific remove order = FIFO (first-in-first-out), allows duplicates,
LinkedList is implementation of the list,
Set is ADT of the collection of elements which disallows duplicates,
Bag is ADT of the collection of elements which allows duplicates.
In general, anything that holds an elements is Collection.
Any collection which allows duplicates is Bag, otherwise it is Set.
Any bag which access elements via index is List.
Bag which appends new element after the last one and has a method to remove element from the head (first index) is Queue.
Bag which appends new element after the last one and has a method to remove element from the tail (last index) is Stack.
Example: In Java, LinkedList is a collection, bag, list, queue and also you can work with it as it was a stack since it support stack operations (add~addLast~push, peekLast, removeLast~pop), so you can call it also stack. The reason, why it does not implement Stack interface is, that peek method is reserved by Queue implementation which retrieves the head of the list (first element). Therefore in case of LinkedList, the "stack methods" are derived from Deque.
Whether Bag contains remove(Object) or not may depend on the implementation e. g. you can implement your own Bag type which supports this operation. Also you can implement get(int) operation to access object on specified index. Time complexity of the get(int) would depend on your implementation e. g. one can implement Bag via linked-list so the complexity would be at average O(n/2), other one via resizable array (array-list) with direct access to the element via index, so the complexity would be O(1).
But the main idea of the Bag is, that it allows duplicates and iteration through this collection. Whether it supports another useful operations depends on implementator's design decision.
Which one of the collection type to use dependes on your needs, if duplicates are not desired, you would use Set instead of Bag. Moreover, if you care about remove order you would pick Stack or Queue which are basically Bags with specific remove order. You can think of Bag as super-type of the Stack and Queue which extends its api by specific operations.
Most of the time, you just need to collect objects and process them in some way (iteration + element processing). So you will use the most simple Bag implementation which is one directional linked-list.
Bag is an unordered collection of values that may have duplicates. When comparing a stack to a bag, the first difference is that for stacks,
order matters.
Bag only supports the add and iterate operations. You cannot remove items from a bag-it’s possible to remove elements from a stack.-. After checking if the container is actually empty, clients can iterate through its elements; since the actual order is unspecified by definition, clients must not rely on it.
Bags are useful when you need to collect objects and process them as a whole set rather than individually. For example, you could collect samples and then, later, compute statistics on them, such as average or standard deviation—the order is
irrelevant in that case.
in terms of priority queues, a bag is a Priority queue for which element
removal (top()-Returns and extracts the element with the highest priority. ) is disabled. Priority Queue api has, top, peek,insert,remove and update methods. it’s possible to peek one element at a time, and the
priority of each element is given by a random number from a uniform distribution. Priorities also change at every iteration.
I got the following issue to solve: I'm with a PriorityQueue of a specific object, and the attribute I use to compare it with others are set with the same value for all the objects.
The problem is: I need to modify one of it's objects (I mean, find it by another attribute, and modify the comparable attribute) and take it off of the queue. And I got no ideia of how to do it, since peek() and poll() just remove and return the head of the queue, and remove() just remove the object, and it's not exactly what I want. I also don't know how could I use Iterator here as well.
That's the code I got until now:
public void inicializaDijkstra(Grafo grafo, Vertice v0){
Comparator<Grafo> comparator = new verticecomparator();
PriorityQueue<Grafo> Queue = new PriorityQueue<Grafo>(grafo.getNumeroDeVertices,grafo);
for (Vertice vertice : conjuntoDeVertices) {
queue.add(vertice);
}
I just though of gettinng the element I want with the Iterator, remove it from the queue, modify it and (if I didn't want to remove it) add it again on the queue. Would it work?
I just thought of getting the element I want with the Iterator, remove it from the queue, modify it and (if I didn't want to remove it) add it again on the queue. Would it work?
It should work1.
Indeed, I can't think of a better / more efficient way of doing this given your data structure choices.
Note that this approach is O(N) where N is the queue length. In a multi-threaded context you would probably need to do the entire sequence under an exclusive lock, and that could make it a concurrency bottleneck.
1 - Actually, with some queue implementations, adding (back) an element while you are iterating the priority queue can result in a ConcurrentModificationException. If that is a problem, then you may need to make a list of elements that need re-inserting and then re-insert them after the you have finished iterating. The javadocs seem to say that PriorityQueue would give CME's but PriorityBlockingQueue would not.
what kind of collection should I use if:
I want to store max. 5 Enums in the collection
Reading, writing and iterating over collection can happen multiple
times per second
If I will need to add new element then the oldest
element will be removed (Assume it has e1...e5 and when I add e6 it will be
e2...e6).
I will be almost always iterating over the whole collection. I guess LinkedList is what I need, but I'm not very experienced in Java, so I want to make sure.
LinkedBlockingQueue
LinkedBlockingQueue lbq =new LinkedBlockingQueue(5);
if(!(lbq.offer(newOBject)){
lbq.take();
lbq.offer(newObject);
}
EnumMap might also be useful, keys restricted to enum instances.
What you need here is a Queue Data Structure which supports FIFO .
You can use LinkedList from Collections Framework.It implements Queue Interface.
Read more about Linked List in Java.
If you do not need to enforce the capacity of the queue you can just use LinkedList. It implements Queue interface, which is what you actually need.
Use it like this:
Queue<EnumClass> queue = new LinkedList<EnumClass>();
queue.offer(newObj);
takenObj = queue.poll();
If you have to limit the size an ArrayBlockingQueue would be a good option, since there will be no additional internal object creation (collection backed by an array).
Queue<EnumClass> queue = new ArrayBlockingQueue<EnumClass>(capacity);
Still, using it with Queue interface would be a good idea. That way you can change the actual implementations at will.
I have collection of elements from which I need to retrieve the least/minimum element.
Normally I would use a PriorityQueue as they are designed specifically for this purpose, and offer O(log(n)) time for dequeing methods.
However, the elements in my array have a dynamic order, ie there natural order changes unpredictably over time. I assume PriorityQueue and other such Sorted collections sort an element when inserted, and then leave it. If this is so PriorityQueue wouldn't work for dynamically-ordered elements. Am I correct in my assumption? Or would PriorityQueue still be appropriate in this situation?
If I can't use PriorityQueue, Collections.min would be my next instinct. However this iterates over the entire collection, which presumably gives O(n) time. Is this the next best solution?
What is the best collection/method to use to retrieve the least element from a collection, given that the natural order of the elements may change unpredictably over time?
Edit:
The order of several elements changes per retrieval operation
Edit 2:
The compare algorithm remains constant, however the values of the fields which it assesses vary unpredictably between retrievals.
I think if the change is truly "unpredictable" you may be stuck with Collections.min(). However, maybe for some other collections like PriorityQueue you could try, before calling for the min.
Add something that you KNOW is the min.
Remove that
Then ask again for the "real" min and hope that your little kludge resorted things...
Alternatively, do you know if the order has changed over time? e.g. some OrderChangedEvent can be fired? If so, recreate the sorted whatever as needed.
A possible way to do this would be to extend PriorityQueue that contains a list as one of the fields. This list will store the java.lang.Object.hashCode() of each object. Whenever an add, peek, poll, offer, etc. is called on the PriorityQueue, the queue will check the hash codes of each element and make see if any element changed. If they have, it will re-order the elements that have changed. Then, it will replace the hashcodes of the changed elements in the list. I don't know how fast this will be, but I suspect it will be faster than O(n).
Without any further assumption on the operations you are going to do, you can't achieve better performance than with a PriorityQueue or another O(log(n))-insert collection (TreeSet , for example, but you lose the O(1)-peek).
As you correctly assumed Collections.min(Collection, Comparator) is a linear operation.
But it depends on how often you need to change the ordering: for example if you only need to change it once in a while and still keep a "standard" ordering, min() is a viable option, but if you need to switch ordering completely then you will probably be better off with reordering the queue/set (that is, traversing and adding all the elements in a new one), tough at a O(nlog(n)) cost. Using Collections.sort(List, Comparator) may be effective if you need a lot of reordering compared to inserts, but requires you to use a List.
Of course if you can make somewhat strong assumptions on the types of sorting you will need (for example, if it can be restricted to a part of the data) you could write your own collection.
Edit:
So you have a (more or less) finite number of orderings (never mind that it's the same type of comparison over different fields, it's different Comparators and that's what matters)? If that's the case, you can probably achieve best performance by using m queues that reference the same objects, each using a different comparator (the simplest method, really). This way you have:
constant time access
O(m*logn(n)) inserts (to insert in every queue)
O(m*n) removals (to remove from every queue)
no ordering costs (as it's handled by the inserts)
slightly larger memory cost (probably negligible)
additional O(n*log(n)) cost the first time a particolar ordering is requested
Supposing a value of m orders of magnitude smaller than n, this is comparable to optimal (single-ordering PriorityQueue) performance. For convenience, you can wrap this into a custom collection that takes a Comparator parameter on retrieval operations, and use it as a key for an HashMap of all the PriorityQueues.
Edit #2:
In that case, there is no better solution than running min() on every retrieval (unless you can make assumptions on the changes of the data); this also means that it's better to just use an ArrayList as the collection, since it has basically the lowest possible cost on every operation and you will not benefit from PriorityQueue's natural ordering anyway. You will end up with linear cost on retrieval (for min) and constant on insertion and deletion: this is optimal as there is no sorting algorithm that has less than Ω(n) and Θ(nlog n) anyway.
As a side note, ordered collections work on the assumption that values will not change after insertion; this is because there is no cost-effective way to monitor the changes nor to reorder them "in place".
Can't you use a java TreeSet which keeps the collection sorted at all times. You need to implement the Comparable interface on your objects to do so. Checkout http://docs.oracle.com/javase/1.4.2/docs/api/java/util/TreeSet.html
Main Question:
I'm seeking some way to give an object within a LinkedList a reference to itself within the list so that it can (efficiently) remove itself from said list (Without sorting through the list looking for itself. I'd like it to just directly cut itself from the list and tie the previous and next items together.).
Less Necessary Details:
I've done a reasonable amount of googling and not found anything other than people advising not to use circular references.
I'd like to do this as I'm designing a game, and in the game objects can implement various interfaces which allow them to be in various lists which are looped through in a prioritized manner. A single object might be in a draw loop, a loop which steps it through the frames of its animation, a high priority logic loop, and a low priority logic loop all at the same time. I would like to implement a removeFrom|TypeOfLoop| method in each appropriate interface so that if an object decides that it no longer needs to be in a loop it can directly remove itself. This keeps the objects that do the actual looping pleasantly simple.
Alternatively, If there is no way to do this, I'm thinking of implementing a flagging system where the list checks to see if each item wants to be removed based on a variable within the item. However, I dislike the idea of doing this enough to possibly just make my own LinkedList that is capable of removing by reference.
I did this recently. I was looking for an O(1) add O(1) remove lock-free Collection. Eventually I wrote my own Ring because I wanted a fixed-size container but you may find the technique I used for my first attempt of value.
I don't have the code in front of me but if memory serves:
Take a copy of Doug Lea's excellent Concurrent Doubly LinkedList and:
Expose the Node class. I used an interface but that is up to you.
Change the add, offer ... methods to return a Node instead of boolean. It is now no longer a java Collection, but see my comment later.
Expose the delete method of the Node class or add a remove method that takes a Node.
You can now remove elements from the list in O(1) time, and it is Lock Free.
Added
Here's an implementation of the remove(Node) method taken from his Iterator implementation. Note that you have to keep trying until you succeed.
public void remove(Node<E> n) {
while (!n.delete() && !n.isDeleted())
;
}
I think your alternative is much better than letting the item remove itself from the loop. It reduces the responsibilities of the objects in the list, and avoids circular references.
Moreover, You could use Guava's Iterables.filter() method and iterate over a filtered list, rather than checking explicitely if the object should be rendered or not at each iteration.
Even if what you want to do was possible, you would get a ConcurrentModificationException when removing an object from the list while iterating on it. The only way to do that is to remove the current object from the iterator.
If you're using LinkedList, there's no more efficient way to remove an item than to iterate over it and do iterator.remove() when you find your element.
If you're using google collections or guava, you can do it in a oneliner:
Iterables.removeIf(list.iterator(), Predicates.equalTo(this));
The easiest way would be changing your algorithm to use Iterator to iterate over List objects and use Iterator.remove() method to remove current element.