Guava's AbstractLinkedIterator class
seems to exist to allow for restarting an iteration in the middle of something like a LinkedHashMap. But I'm failing to find any classes in guava that ever return this. Is there, in fact, a way to iterate a LinkedHashMap or a LinkedHashMultimap via a subclass of one of these?
AbstractLinkedIterator, as its Javadoc states:
provides a skeletal implementation of the Iterator interface for sequences whose next element can always be derived from the previous element.
That's all it's for. It doesn't have any knowledge of, say, a current linked entry in in a LinkedHashMap. If you had access to the nodes of a linked structure and you made this an Iterator<Node> you could of course compute the next node from the previous one, but LinkedHashMap doesn't expose its linked entries.
This link says there are no uses as yet (02/05/2011) and i certainly couldn't find any either. Looking at the source code this is a very skeletal implementation which just calls down to it's inheritors to ask them what the next might be based on the current element but you'd have to implement the meat of it yourself (which might indeed give you your Iterators that can start from any point in some ordered set/list). What is it you're trying to do?
AbstractLinkedIterator is very useful for creating Iterators and Iterables that represent reccurances - e.g. potentially infinite Iterable with prime numbers etc.
If you need to restart the iteration, just use the Iterable to create new Iterator.
Related
The List javadocs mentions that Lists are ordered. However, I cannot see anything specifying the nature of the ordering. Can we rely on lists e.g. ArrayList and LinkedList maintaining insertion order?
I am asking about the instance where we do not call set or sort.
However, I cannot see anything specifying the nature of the ordering.
Funnily enough, it's mentioned in the second sentence of its documentation:
The user of this interface has precise control over where in the list each element is inserted.
Without calling List#set or List#sort, the only methods that will add elements to the List are List#add and List#addAll, both of which append them to the end (unless you call one of the overloaded methods and specify an index); you can also add elements to the List via its ListIterator.
If List did not maintain insertion order, it would have mentioned it in its documentation. If you're still unsure, feel free to look over the source code, which is available online.
Is there a java collection interface that guarantees no duplicates as well as the preservation of insertion order at the same time?
This is exactly what LinkedHashSet is doing? However, I am wondering if there is also an interface guaranteeing the same thing in order to avoid direct dependency on some specific class?
SortedSet is referring only to the natural order (and is not implemented by LinkedHashSet).
Essentially, I am looking for an interface that would indicate that the iteration order of elements is significant (and at the same time it contains no duplicates, i.e., List obviously would not apply).
Thanks!
UPDATE this question is not asking for an implementation or a data structure (as in the question to which this was marked as a duplicate). As several people pointed out as clarification, I am looking for an interface that demands both properties (no duplicates and significant order) in its contract. The application for this would be that I can return objects of this type to clients without promising any specific implementation.
UPDATE 2 Moreover, the related question specifically asks for preserving duplicates in contrast to this question. So I am pretty certain it is not a duplicate.
No interface in the JDK collections provides that.
You could try to build it by combining Set and List. Any collection implementing Set should not allow duplicate elements, and any collection implementing List should maintain order.
But then, no class in the JDK collection implements both Set and List. Because unfortunately LinkedHashSet does not implement List.
Of course, you could build one implementation easily by wrapping a LinkedHashSet (by composition patter, not by derivation) and adding a get(int i) method, or by wrapping an ArrayList (again by composition) and throwing an IllegalArgumentException when trying to add a new element.
The most tricky part IMHO would be the addAll method as both interfaces define it with different semantics (emphasize mine) :
Set: Adds all of the elements in the specified collection to this set if they're not already present
List : Appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's iterator
As you cannot meet both requirements is source collection contains duplicates, my advice would be that addAll throws an IllegalArgumentException in that case, or more simply that it always throw an UnsupportedOperationException as addAll is an optional operation for both interfaces
I have a set of elements with unique ids.
I want to order them somehow, so given an element id I return its previous and next element effectively.
If I would implement it in any language with pointers I would have created a hashTable with and each node in the doublely linked list will point to the previous and next element respectively.
how would you implement it in java?
btw, should I use hashMap/hashtable or hashSet?
If you want to actually use a doubly linked list view over a hash table, the best way to do so is to implement it yourself. Each node knows the value of its content, the next element in the bucket (singly linked buckets are easy), and the previous/next elements in the doubly linked list. You are then free to implement ListIterator providers and weird Deque implementations as much as you like.
It's a little bit like reinventing the wheel honestly, but there are no standard hash implementations that also provide truly useful access to the linked list outside their iterator.
See this class that I wrote; it's a Set not a Map, and it has some extra fancy stuff in it (for the purposes of getting a random element instead of the most recent or last-added), but it should give you some ideas. I also recommend reading the sourcecode for java.util.HashMap and taking hints from the way they do their hashing etc.
Keep in mind: If you want to maintain an actual sorted set, hash tables are not what you should be using. If you need it to be always sorted, get a sorted tree set; those are also quite traversable.
Edit: Included the link to the class because I'm bad and I forgot
I am considering using a Java collection that would work best with random insertions. I will be inserting a lot and only read the collection once at the end.
My desired functionality is adding an element at a specified index, anywhere between <0, current_length>. Which collection would be the most efficient to use?
Useful link for your reference:
http://www.coderfriendly.com/wp-content/uploads/2009/05/java_collections_v2.pdf
Not entirely sure how you will be reading the information post input (and how important it is to you). Hashmap or ArrayList would make sense depending on what you are looking to do. Also not sure if you are looking for something thread safe or not.
Hope it helps.
The inefficiency of using List is endemic to the problem. Every time you add something, every subsequent element will have to be re-indexed - as the javadoc states:
Shifts the element currently at that position (if any) and any
subsequent elements to the right (adds one to their indices).
From your question/comments, it would appear that you have a bunch of Objects, and you're sorting them as you go. I'd suggest a more efficient solution to this problem would be to write a Comparator (or make your object implement Comparable), and then use Collections.sort(list, comparator) (or Collections.sort(list)).
You might suggest that your Objects are being sorted on the basis of other variables. In which case, you could create an extension of the Object, with those other variables as fields and extending Comparable, and with a method like getOriginal(). You add these wrapped objects to your list, sort, and then iterate through the list, adding the original objects (from getOriginal()) to a new list.
For info on the sorting algorithm of collections - see this SO question
I have a multiset in guava and I would like to retrieve the number of instances of a given element without iterating over this multiset (I don't want to iterate because I assume that iterating takes quite some time, as it looks through all the collection).
To do that, I was thinking first to use the entryset() method of multiset, to obtain a set with single instances and their corresponding count. Then, transform this set into a hashmap (where keys are the elements of my set, and values are their instance count). Because then I can use the methods of hashmap to directly retrieve a value from its key - done! But this makes sense only if I can transform the set into the hashmap in a quick way (without iterating trhough all elements): is it possible?
(as I said I expect this question to be flawed on multiple counts, I'd be happy if you could shed light on the conceptual mistakes I probably make here. Thx!)
Simply invoke count(element) on your multiset -- voila!
You may know in Guava Multiset is an interface, not a class.
If you just want to know the repeated number of an element, call Multiset.count(Object element).
Please forget my following statement:
Then if you are using a popular implementation HashMultiset, there is already a HashMap<E, AtomicInteger> working under the scene.
That is, when the HashMultiset iterates, also a HashMap iterates. No need to transform into another HashMap.