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.
Related
PriorityQueue<Integer> pq = new PriorityQueue<>(); // first
Queue<Integer> pq = new PriorityQueue<>(); // second
My Question:
Which one is better? I see many examples use first one, however I also heard program against interface. The type of declaration should be as general as possible. PriorityQueue implements Queue interface, therefore from second argument, we should use second one.
PS:
This example is quite different from ArrayList<Integer> list = new ArrayList<>() vs
List<Integer> list = new ArrayList<>(), since I never see any production codes use the first one for ArrayList and we always use the second one. However, I really see many examples use the first one for PriorityQueue.
You should use an interface general enough to fit your needs and not impose implementation details, but specific enough to fit your exact use case.
If you need some queue without any use of prioritization functionality (e.g. your code does not use any knowledge of prioritization), then use Queue. That way you can change actual implementation within single line.
If your code uses prioritization features and rely on them, then you definitely should use PriorityQueue, because Queue will be too general and will lead to errors when prioritization methods are called.
From Javadoc:
Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries.
If it is so, then why doesn't it provide object access like List in java,
list.get(index);
UPDATE
I had implemented LRU Cache using LinkedHashMap. My algorithm required me to access LRU Object from the cache. That's why I required random access, but I think that will cost me bad performance, so I have changed the logic and I am accessing the LRU object just when Cache is full...using removeEldestEntry()
Thank you all...
a) Because the entries are linked, not randomly accessible. The performance would be miserable, O(N) if I'm not in error.
b) Because there is no interface to back up this functionality. So the choice would be to either introduce a dedicated interface just for this (badly performing) Implementation or require clients to program against implementation classes instead of interfaces
Btw with Guava there's a simple solution for you:
Iterables.get(map.values(), offset);
And for caching look at Guava's MapMaker and it's expiration features.
Since values() provides a backing collection of the values, you can solve it like this:
map.values().remove(map.values().toArray()[index]);
Perhaps not very efficient (especially memory-wise), but it should be O(N) just as you would expect it to be.
Btw, I think the question is legitimate for all List operations. (It shouldn't be slower than LinkedList anyway, right?)
I set out to do a LinkedHashMapList which extended the LinkedHashMap and implemented the List interface. Surprisingly it seems impossible to do, due to the clash for remove. The existing remove method returns the previously mapped object, while the List.remove should return a boolean.
That's just a reflection, and honestly, I also find it annoying that the LinkedHashMap can't be treated more like a LinkedList.
It provides an Iterator interface, each node in the list is linked to the one before it and after it. Having a get(i) method would be no different than iterating over all the elements in the list since there is no backing array (same as LinkedList).
If you require this ability which isn't very performant I suggest extending the map yourself
If you want random access you can do
Map<K,V> map = new LinkedHashMap<K,V>();
Map.Entry<K,V>[] entries = (Map.Entry<K,V>[]) map.toArray(new Map.Entry[map.size()]);
Map.Entry<K,V> entry_n = entry[n];
As you can see the performance is likely to be very poor unless you cache the entries array.
I would question the need for it however.
There is no real problem to make a Map with log(N) efficiency of access by index. If you use a red-black tree and store for each node the number of elements in the tree starting at that node it is possible to write a get(int index) method that is log(N).
I have a scenario where an unknown amount of threads add elements to a collection on a server. The data in this collection doesn't have to be sorted and it also won't be iterated. Only two simple operations shall work on this collection:
Adding an element (and removing old element in some cases)
Reading all elements from the collection (not one by one, but the whole collection in order to serialize it and send it to a client. Of course the elements could also be moved to another collection which is then serialized afterwards.)
Which collection would be ideal for this use case? I would choose ConcurrentHashMap, bu I don't know if this choice is good.
Edit: I've forgotten one important requirement: If an element of a certain kind is already in this collection and another one of the same kind is added, then the old one shall be removed before the new one is added. For this requirement I wanted to use hash values to avoid searching. The objects that are stored are simple: They contain a unique user name and some strings and ints. The object's user name should be used as key.
Yes, ConcurrentHashMap is appropriate for this. Use the user name as key type (K) and the associated user information ("some strings and ints") as value type (V) in the map. Use put to add new key-value pairs, remove to remove key-value pairs, and entrySet to get all key-value pairs in the container (if that is what you meant by "reading all elements from the collection").
i think the best thing to use is actually ConcurrentSkipListSet . the reason:
Iterators are weakly consistent, returning elements reflecting the
state of the set at some point at or since the creation of the
iterator. They do not throw ConcurrentModificationException, and may
proceed concurrently with other operations. Ascending ordered views
and their iterators are faster than descending ones.
this means you can go over the entire list and read all of the items, while adding other items. it's completely concurrent !
do note that adding items take O(logN) time.
I believe there is a concurrent list implementation in java.util.concurrent. CopyOnWriteArrayList which can be useful for your requirement.
or you can use :
List<Object> objList = Collections.synchronizedList(new ArrayList<Object>());
It's not part of the standard library, but you can use this concurrent doubly linked list. Its iterator is weakly consistent and won't throw a ConcurrentModificationException, or you can use toArray and loop through the returned array.
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.
if you look at the LinkedList methods of Java, it does offer operations for Queue, Stack, Deque.
And I am aware that you can implement Queue, Stack or Deque with a LinkedList. If you look at C# implementation though, Queue and Stack uses arrays.
My Curiosity is, why they offer a push(T e) method for a linked list?
Why Queue and Stack are not separate classes, just like C#.
Below is the code for push and pop which is duhhh. But why?
public void push(Object obj)
{
addFirst(obj);
}
public Object pop()
{
return removeFirst();
}
If you look at HashMap, or HashSet, it uses array internally, and there is LinkedHashSet and map correspondingly to keep ordering.
This is not really confusing, but it doesnt make sense really.
Why java has such implementation?
Focus on data structure implementation:
Linked list is efficient for frequent add and remove. (as Queue and Stack usually do, and iteration operation is rare). Array is not, it needs array-copy operation which is time consuming.
A double-linked list such as Java's LinkedList is a rather flexible data structure, so it makes sense to implement several data structures using it as a base. So if you want to view it as a Queue, you'd say something like this (I'm omitting type parameters):
Queue q = new LinkedList();
If you want to use it as a stack, you would declare it like this:
Deque s = new LinkedList();
And so on. It all boils down to code reutilization, after all, why implement several different classes for similar functionality, when a single class (LinkedList in this case) suffices?
Basic OOD: while perhaps a fuzzy line, Queue, Stack, and Deque roughly describe operations you can perform on a collection and hence deserve to be interfaces. LinkedList describes the implementation and performance characteristics of an interface and hence deserves to be a class. That implementation could be (is) exposed as multiple interfaces. To me, the real question is, "Why is Stack a class?"
LinkedList implements Queue interface because you might want to use the linked list as a Queue in some places. What this means is that a method which takes a queue as input param can also process linked lists. The following works
List<String> linkedList = new LinkedList<String>();
linkedList.add("element1");
linkedList.add("element2");
Queue<String> q = (Queue<String>)linkedList;
q.poll(); //removes and returns element1 from the linkedList
Java has a separate class called java.util.Stack which extends from vector which in turn is a array based implementation. But this is a thread safe version. If you don't worry about thread safety, then you can use ArrayDeque as a stack.
Queue is an interface, and has other implementations besides LinkedList. There's also a Stack class.
Ultimately, it just seems like an arbitrary decision, and the underlying implementation doesn't really matter that much (IMO).