Reputation: 39721
I'm using LinkedHashSet
. I want to insert items at the 0th position, like:
Set<String> set = new LinkedHashSet<String>();
for (int i = 0; i < n; i++) {
set.add(0, "blah" + i);
}
I'm not sure how LinkedHashSet
is implemented, is inserting going to physically move all addresses of current items, or is it the same cost as inserting as in a linked-list implementation?
Complete mess up by me: was referencing the ArrayList
docs. The Set
interface has no add(index, object)
method. Is there a way to iterate over the set backwards then? Right now to iterate I'm doing:
for (String it : set) {
}
Can we do that in reverse?
Upvotes: 3
Views: 10324
Reputation: 80031
To answer your latest question, there is no reverse iterator feature available from LinkedHashSet
, even though internally the implementation uses a doubly linked list.
There is an open Request For Enhancement about this: JDK-4848853.
The Guava library has a Lists.reverse
method, though it actually generates a reverse list.
Upvotes: 0
Reputation: 21315
Starting with Java 21, the reversed()
method can be used to return a reversed view on the set, which can then be iterated over in the standard manners (such as using an enhanced for
statement):
for (String it : set.reversed()) {
System.out.println(it);
}
Upvotes: 0
Reputation: 21315
Java 21 added the addFirst
method to LinkedHashSet
, which adds an element to the start of the set.
Adds an element as the first element of this collection (optional operation). After this operation completes normally, the given element will be a member of this collection, and it will be the first element in encounter order.
Upvotes: 2
Reputation: 4297
Sets are, by definition, independent of order. Thus, Set doesn't have add(int , Object) method available.
This is also true of LinkedHashSet http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
LinkedHashSet maintains insertion order and thus all elements are added at the end of the linked list. This is achieved using the LinkedHashMap. You can have a look at the method linkEntry in LinkedHashMap http://www.docjar.com/html/api/java/util/LinkedHashMap.java.html
Edit: in response to edited question
There is no API method available to do this. But you can do the following
ArrayList(Set)
Collections.reverse(List)
Upvotes: 7
Reputation: 110094
You can't add elements to the front of a LinkedHashSet
... it has no method such as add(int, Object)
nor any other methods that make use of the concept of an "index" in the set (that's a List
concept). It only provides consistent iteration order, based on the order in which elements were inserted. The most recently inserted element that was not already in the set will be the last element when you iterate over it.
And the Javadoc for LinkedHashSet
explicitly states:
Like HashSet, it provides constant-time performance for the basic operations (add, contains and remove), assuming the hash function disperses elements properly among the buckets.
Edit: There is not any way to iterate over a LinkedHashSet
in reverse short of something like copying it to a List
and iterating over that in reverse. Using Guava you could do that like:
for (String s : Lists.reverse(ImmutableList.copyOf(set))) { ... }
Note that while creating the ImmutableList
does require iterating over each element of the original set, the reverse
method simply provides a reverse view and doesn't iterate at all itself.
Upvotes: 0
Reputation: 1725
As already mentioned, LinkedHashSet is build on LinkedHashMap, which is built on HashMap :) Javadocs says that it takes constant time to add an element into HashMap, assuming that your hash function is implemented properly. If your hash function is not implemented well, it may take up to O(n). Iteration backwards in not supported at this moment.
Upvotes: -1
Reputation: 2845
Judging by the source code of LinkedHashMap (which backs LinkedHashSet -- see http://www.docjar.com/html/api/java/util/LinkedHashMap.java.html ), inserts are cheap, like in a linked list.
Upvotes: 0