Are deques (double-ended queues) traversable data structures? Does it make a difference whether they are have an array-based implementation vs linked implementation?
Yes, deques is traversable data structure, you can get interator from deque for traversing. Functionally, It does not make difference. But, technically and data structure wise, it make a difference. Remember, when we are using list we can add node dynamically. But, when using array, we need to define the size of deque or default size is used. Now, if you insert another element then it will create new array of double size and copy old array into new array then insert the new element.
Yes, they are traversable. Especially in JAVA Deque API, you can always get either iterator (or) descendingIterator to traverse the Deque either from first to last (or) from last to first respectively.
For just traversing the Deque, the underlying implementation may not make much difference. But for other operations it does. People usually prefer ArrayDeque over LinkedList. For more information on this follow the thread Why is ArrayDeque better than LinkedList.
Also look at the corresponding JAVA APIs to get the major differences between these two different implementations.
No. Like the structures it is a hybrid of (i.e., stacks and queues), deques (or double-ended queues) are not designed to be traversable. In fact, they are specifically designed not to be traversable. If the capability of traversing items contained within is necessary for a particular application, then a dequeue is probably not the best data structure to use in that case.
Related
I notice that linkedList has some methods like pop and push. Typically, if I want to use the feature of stack (FILO).Would the linkedList be the best choice?
LinkedList will work, and in fact implements the most stack-like interface in the JDK, Deque.
ArrayDeque is the other main non-threadsafe implementation, and is probably more efficient if you only need the stack operations. The above link for Deque lists the other two JDK-provided implementations, which are thread safe.
There is no better or worse approach to implement a stack but they have different advantages.
Implementation based on linked list gives you more flexibility over the container's capacity since you can theoretically always add more elements to it. Array based stack is more limited in terms of capacity. Linked list implicate more space overhead though, as you need to store references to other nodes.
Performance wise with a stack you only access the top element which means you don't need the random access feature that an array gives you over linked lists.
I have a situation where I have need a data structure that I can add strings to. This data structure is very large.
The specific qualities I need it have are:
get(index)
delete a certain number of entries that were added initially when the limit exceeds.(LIFO)
I've tried using an ArrayList but the delete operation is o(n) and for a linkedList the traverse or get() operation will be o(n).
What other options do I have?
circular buffer - one thats implemented with an array under the hood.
LinkedHashSet might be of interest. It is effectively a HashSet but it also maintains a LinkedList to allow a predictable iteration order - and therefore can also be used as a FIFO queue, with the nice added benefit that it can't contain duplicate entries.
Because it is a HashSet too, searches (as opposed to scans) can be O(1) if they can match on equals()
You can have a look at this question and this too.
If I am going to create a Java Collection, and only want to fill it with elements, and then iterate through it (without knowing the necessary size beforehand), i.e. all I need is Collection<E>.add(E) and Collection<E>.iterator(), which concrete class should I choose? Is there any advantage to using a Set rather than a List, for example? Which one would have the least overhead?
which concrete class should I choose?
I would probably just go with an ArrayList or a LinkedList. Both support the add and iterator methods, and neighter of them have any considerable overhead.
Is there any advantage to using a Set rather than a List, for example?
No, I wouldn't say so. (Unless you rely on the order of the elements, in which case you must use a List, or want to disallow duplicates, in which case you should use a Set.)
(I don't see how any Set implementation could beat a list implementation for add / iterator methods, so I'd probably go with a List even if I don't care about order.)
Which one would have the least overhead?
Sounds like micro benchmarking here, but if I'd be forced to guess, I'd say ArrayList (or perhaps LinkedList in coner cases where ArrayLists need to reallocate memory often :-)
Do not go with a Set. Sets and Lists differ according to their purpose, that you should always consider when choosing the right Collection
a List is there for maintaining elements in the order you added them; and if you insert the same element twice it will be kept twice
a Set is there for holding one specific element exactly once (uniqueness); order is only relevant for specific implementations (like TreeSet), but still elements that are 'the same' would not be added twice
Set is only meaningful if you want to sort your objects and to make sure no duplicate element is 'registered'. Else, an ArrayList is just fine.
However, if you want to add elements while iterating too, an ArrayBlockingQueue is better.
Here are some key points which can help you to choose your collection according to your requirement -
List(ArrayList or LinkedList)
Allowed duplicate values.
Insertion order preserved.
Set
Not allowed duplicate values.
Insertion order is not preserved.
So according to your requirement List seems to be a suitable choice.
Now Between ArrayList and LinkedList -
ArrayList is a random access list. Use if your frequent operation is the retrieval of elements.
LinkedList is the best option if you want to add or remove elements from the list.
I have 100,000 objects in the list .I want to remove few elements from the list based on condition.Can anyone tell me what is the best approach to achieve interms of memory and performance.
Same question for adding objects also based on condition.
Thanks in Advance
Raju
Your container is not just a List. List is an interface that can be implemented by, for example ArrayList and LinkedList. The performance will depend on which of these underlying classes is actually instantiated for the object you are polymorphically referring to as List.
ArrayList can access elements in the middle of the list quickly, but if you delete one of them you need to shift a whole bunch of elements. LinkedList is the opposite i nthis respect., requiring iteration for the access but deletion is just a matter of reassigning pointers.
Your performance depends on the implementation of List, and the best choice of implementation depends on how you will be using the List and which operations are most frequent.
If you're going to be iterating a list and applying tests to each element, then a LinkedList will be most efficient in terms of CPU time, because you don't have to shift any elements in the list. It will, however consume more memory than an ArrayList, because each list element is actually held in an entry.
However, it might not matter. 100,000 is a small number, and if you aren't removing a lot of elements the cost to shift an ArrayList will be low. And if you are removing a lot of elements, it's probably better to restructure as a copy-with filter.
However, the only real way to know is to write the code and benchmark it.
Collections2.filter (from Guava) produces a filtered collection based on a predicate.
List<Number> myNumbers = Arrays.asList(Integer.valueOf(1), Double.valueOf(1e6));
Collection<Number> bigNumbers = Collections2.filter(
myNumbers,
new Predicate<Number>() {
public boolean apply(Number n) {
return n.doubleValue() >= 100d;
}
});
Note, that some operations like size() are not efficient with this scheme. If you tend to follow Josh Bloch's advice and prefer isEmpty() and iterators to unnecessary size() checks, then this shouldn't bite you in practice.
LinkedList could be a good choice.
LinkedList does "remove and add elements" more effective than ArrayList. and no need to call such method as ArrayList.trimToSize() to remove useless memory. But LinkedList is a dual-linked list, each element is wrapped as an Entry which needs extra memory.
Recently a coworker showed me some code he had written with a LinkedList and I couldn't get my head around it.
a -> b -> c -> d -> e -> f
If I want to get d from the LinkedList, don't I have to traverse the list starting with a and iterating up to d or starting with f and iterating back to d?
Why would I care WHERE d is stored physically in the Collection?
Not every linked list is linked in both directions but, normally, yes. This type of collection features sequential access in the forward or forward and reverse directions.
The advantages are:
least amount of memory overhead except for a flat array
very fast insert and delete
memory can be allocated and released one element at a time
easy to implement (not so important with modern languages but it was important in C89 and C99)
LIFO or FIFO ordering is possible
I think that the right question is not WHERE, but HOW it stored your collection. According to this, your time of adding, searching, deleting and keeping your collection consistent is different. So, when you choose your type collection you should keep in mind, what will be the most frequent operation and pick the best solution for your case.
Linked lists typically have better performance characteristics than arrays for adding and removing elements.
And yes, if you're operating on sorted data, you do normally care what order elements are stored in.
You probably don't care, regardless of whether you're using a LinkedList or an ArrayList. LinkedLists offer the advantage of being able to easily add elements to the beginning of a list, which you can't do with an ArrayList.
Lists are not about "physical locations" (whatever you mean by that), lists are a certain data structure that can grow and shrink and provide decent complexity across the various operations.
You don't have to explicitly traverse the linked list, as LinkedList offers indexOf(Object) and get(int). These will still traverse the list, but will do it implicitly.
You'll care about how a collection orders items because this affects efficiency of operations on the collection, particularly insert, fetch & removal. Any ordering on the items in a collection also affect timing of algorithms that use the data structure.