Let's say the List b is a LinkedList.
Let's say the List a is also a LinkedList.
Question:
How do I append these list in constant time?
It is possible, because LinkedList is presumably a doubly linked list (otherwise it couldn't implement the Deque interface). And appending doubly linked list is a 0(1) operation.
The addAll method doesn't run in constant time.
Question:
How do I transform a LinkedHashSet into a list in constant time?
It is also presumably possible because LinkedHashSet "maintains a doubly-linked list running through all of its entries".
Your assumptions are based on no encapsulation - i.e. that the LinkedHashSet is willing to expose its internal LinkedList to the outside world, when I suspect it isn't.
Likewise joining two linked lists - I don't know offhand whether each node knows which list it's in, but that's certainly a possibility which would scupper your constant-time appending. Even if they don't, as soon as you attach the head of one list to the tail of the other, you end up with problems - you've got two lists both referring to the same data, which would have some odd consequences.
In other words, both of these operations are feasible in a computer science sense, and you could build your own implementations to support them, but that doesn't mean the Java API exposes its internals in a way which enables those operations.
You would need to implement your own classes. The LinkedList class does not expose its internal node structure, so you can't just point its last node to the first node of another LinkedList.
The answer is similar for the LinkedHashSet: While it does maintain this doubly-linked list, you don't get to access it.
You do not get access to it but I suspect that Collections does, so you should not give up hope that this is a viable and quick solution to your problem.
I looked further and you are right. If you have Set<Whatever> whatever = SOME CONSTRUCTOR then you can code List<Whatever> list = new LinkedList(whatever); because a LinkedList has a Collections constructor and Set has a Collections interface.
Related
If we are implementing a LRU cache using HashMap and DoublyLinkedList, What is the best way to implement evict() method with O(1) time complexity?
LinkedList from Java didn't expose the Node type (which is a private static inner class).
So you can't remove it in in O(1), because a sequential scan is required.
To get O(1), you need to be able to access the Node type, so that could remove it without scan.
You have to write it by yourself. Fortunately, a doubly linked list is relatively easy to write, and it's a pretty beneficial & fun task to do.
How to remove with a given Node?
Refer to this answer: https://stackoverflow.com/a/54593530
The method LinkedList.java -> removeNode() remove a given node, without sequential scan.
The code in this answer is for a singly linked list, the remove for a doubly linked list is even simpler in some case.
Tips:
If the given node is the end node in linked list, then you need the previous node too.
But that's for singly linked list, for a doubly linked node, the node itself contains the previous node, so you don't have to pass previous node to the removeNode() method.
BTW
Why it's beneficial?
linked list is the most basic structure (except array and bits), that some other very basic structures could built base on.
e.g both queue and stack could be implemented easily with a linked list.
Concurrent access
java.util.LinkedList is not thread-safe, your LRU might needs some concurrent control, but I'm not sure.
If need, then java.util.concurrent.ConcurrentLinkedDeque is a good example to refer to.
#Update LinkedHashMap
java.util.LinkedHashMap, is a combination of hashtable & doubly linked list.
Mechanism:
It extends HashMap to get the O(1) complexity for the common operations.
And use doubly linked list to keep track of insertion order.
head is the eldest item, and tail is the newest item.
It can be used to impl some kind of cache, though I am not sure will it be fully qualified for your requirement.
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.
In my program I often use collections to store lists of objects. Currently I use ArrayList to store objects.
My question is: is this a best choice? May be its better to use LinkedList? Or something else?
Criteria to consider are:
Memory usage
Performance
Operations which I need are:
Add element to collection
Iterate through the elements
Any thoughts?
Update: my choice is : ArrayList :) Basing on this discussion as well as the following ones:
When to use LinkedList over ArrayList?
List implementations: does LinkedList really perform so poorly vs. ArrayList and TreeList?
I always default to ArrayList, and would in your case as well, except when
I need thread safety (in which case I start looking at List implementations in java.util.concurrent)
I know I'm going to be doing lots of insertion and manipulation to the List or profiling reveals my usage of an ArrayList to be a problem (very rare)
As to what to pick in that second case, this SO.com thread has some useful insights: List implementations: does LinkedList really perform so poorly vs. ArrayList and TreeList?
I know I'm late but, maybe, this page can help you, not only now, but in the future...
Linked list is faster for adding/removing inside elements (ie not head or tail)
Arraylist is faster for iterating
It's a classic tradeoff between insert vs. retrieve optimization. Common choice for the task as you describe it is the ArrayList.
ArrayList is fine for your (and most other) purposes. It has a very small memory overhead and has good amortized performance for most operations. The cases where it is not ideal are relatively rare:
The list ist very large
You frequently need to do one of these operations:
Add/remove items during iteration
Remove items from the beginning of the list
If you're only adding at the end of the list, ArrayList should be ok. From the documentation of ArrayList:
The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost
and ArrayList should also use less memory than a linked list as you don't need to use space for the links.
It depends on your usage profile.
Do you add to the end of the list? Both are fine for this.
Do you add to the start of the list? LinkedList is better for this.
Do you require random access (will you ever call get(n) on it)? ArrayList is better for this.
Both are good at iterating, both Iterator implementations are O(1) for next().
If in doubt, test your own app with each implementation and make your own choice.
Given your criteria, you should be using the LinkedList.
LinkedList implements the Deque interface which means that it can add to the start or end of the list in constant time (1). In addition, both the ArrayList and LinkedList will iterate in (N) time.
You should NOT use the ArrayList simply because the cost of adding an element when the list is full. In this case, adding the element would be (N) because of the new array being created and copying all elements from one array to the other.
Also, the ArrayList will take up more memory because the size of your backing array might not be completely filled.
What are the advantages of each structure?
In my program I will be performing these steps and I was wondering which data structure above I should be using:
Taking in an unsorted array and
adding them to a sorted structure1.
Traversing through sorted data and removing the right one
Adding data (never removing) and returning that structure as an array
When do you know when to use a TreeSet or LinkedList? What are the advantages of each structure?
In general, you decide on a collection type based on the structural and performance properties that you need it to have. For instance, a TreeSet is a Set, and therefore does not allow duplicates and does not preserve insertion order of elements. By contrast a LinkedList is a List and therefore does allow duplicates and does preserve insertion order. On the performance side, TreeSet gives you O(logN) insertion and deletion, whereas LinkedList gives O(1) insertion at the beginning or end, and O(N) insertion at a selected position or deletion.
The details are all spelled out in the respective class and interface javadocs, but a useful summary may be found in the Java Collections Cheatsheet.
In practice though, the choice of collection type is intimately connected to algorithm design. The two need to be done in parallel. (It is no good deciding that your algorithm requires a collection with properties X, Y and Z, and then discovering that no such collection type exists.)
In your use-case, it looks like TreeSet would be a better fit. There is no efficient way (i.e. better than O(N^2)) to sort a large LinkedList that doesn't involve turning it into some other data structure to do the sorting. There is no efficient way (i.e. better than O(N)) to insert an element into the correct position in a previously sorted LinkedList. The third part (copying to an array) works equally well with a LinkedList or TreeSet; it is an O(N) operation in both cases.
[I'm assuming that the collections are large enough that the big O complexity predicts the actual performance accurately ... ]
The genuine power and advantage of TreeSet lies in interface it realizes - NavigableSet
Why is it so powerfull and in which case?
Navigable Set interface add for example these 3 nice methods:
headSet(E toElement, boolean inclusive)
tailSet(E fromElement, boolean inclusive)
subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)
These methods allow to organize effective search algorithm(very fast).
Example: we need to find all the names which start with Milla and end with Wladimir:
TreeSet<String> authors = new TreeSet<String>();
authors.add("Andreas Gryphius");
authors.add("Fjodor Michailowitsch Dostojewski");
authors.add("Alexander Puschkin");
authors.add("Ruslana Lyzhichko");
authors.add("Wladimir Klitschko");
authors.add("Andrij Schewtschenko");
authors.add("Wayne Gretzky");
authors.add("Johann Jakob Christoffel");
authors.add("Milla Jovovich");
authors.add("Taras Schewtschenko");
System.out.println(authors.subSet("Milla", "Wladimir"));
output:
[Milla Jovovich, Ruslana Lyzhichko, Taras Schewtschenko, Wayne Gretzky]
TreeSet doesn't go over all the elements, it finds first and last elemenets and returns a new Collection with all the elements in the range.
TreeSet:
TreeSet uses Red-Black tree underlying. So the set could be thought as a dynamic search tree. When you need a structure which is operated read/write frequently and also should keep order, the TreeSet is a good choice.
If you want to keep it sorted and it's append-mostly, TreeSet with a Comparator is your best bet. The JVM would have to traverse the LinkedList from the beginning to decide where to place an item. LinkedList = O(n) for any operations, TreeSet = O(log(n)) for basic stuff.
The most important point when choosing a data structure are its inherent limitations. For example if you use TreeSet to store objects and during run-time your algorithm changes attributes of these objects which affect equal comparisons while the object is an element of the set, get ready for some strange bugs.
The Java Doc for Set interface state that:
Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.
Interface Set Java Doc
Maybe the title is not appropriate but I couldn't think of any other at this moment. My question is what is the difference between LinkedList and ArrayList or HashMap and THashMap .
Is there a tree structure already for Java(ex:AVL,red-black) or balanced or not balanced(linked list). If this kind of question is not appropriate for SO please let me know I will delete it. thank you
ArrayList and LinkedList are implementations of the List abstraction. The first holds the elements of the list in an internal array which is automatically reallocated as necessary to make space for new elements. The second constructs a doubly linked list of holder cells, each of which refers to a list element. While the respective operations have identical semantics, they differ considerably in performance characteristics. For example:
The get(int) operation on an ArrayList takes constant time, but it takes time proportional to the length of the list for a LinkedList.
Removing an element via the Iterator.remove() takes constant time for a LinkedList, but it takes time proportional to the length of the list for an ArrayList.
The HashMap and THashMap are both implementations of the Map abstraction that are use hash tables. The difference is in the form of hash table data structure used in each case. The HashMap class uses closed addressing which means that each bucket in the table points to a separate linked list of elements. The THashMap class uses open addressing which means that elements that hash to the same bucket are stored in the table itself. The net result is that THashMap uses less memory and is faster than HashMap for most operations, but is much slower if you need the map's set of key/value pairs.
For more detail, read a good textbook on data structures. Failing that, look up the concepts in Wikipedia. Finally, take a look at the source code of the respective classes.
Read the API docs for the classes you have mentioned. The collections tutorial also explains the differences fairly well.
java.util.TreeMap is based on a red-black tree.
Regarding the lists:
Both comply with the List interface, but their implementation is different, and they differ in the efficiency of some of their operations.
ArrayList is a list stored internally as an array. It has the advantage of random access, but a single item addition is not guaranteed to run in constant time. Also, removal of items is inefficient.
A LinkedList is implemented as a doubly connected linked list. It does not support random access, but removing an item while iterating through it is efficient.
As I remember, both (LinkedList and ArrayList) are the lists. But they have defferent inner realization.