How to add element at specific index/position in HashSet? - java

I have some HashSet collection of String elements, how I can add new element at specific position? I saw documentation and didn't find any method that can do it.

One of the aspects of a standard HashSet<T> is that it is unordered. So you cannot insert an element at a specific index. Or as is specified in the documentation:
This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.
When you do an insertion, deletion, etc. it is possible that the HashSet<T> will do a rehashing. As a result the order of the elements in a for(...) loop can change completely.
There exists an extension of a Hashset<T>, the LinkedHashSet<T> which maintains the order of the elements in which they were inserted.
A TreeSet<T> on the other hand, uses a tree, and orders the elements according to an order relation (an object that is less than another object, is emitted before that element).
It would be weird if you could insert an element at a random index, since that would result in O(n) time for at least some operations with a specific index. Usually one uses a HashSet<T> to perform insertions, removal, etc. in O(1) (average time).

we can see pic use list to add at particular index and then add that list to set using object.addAll(listobject or setobject
Set<Integer> s=new HashSet<Integer>();
Set<Integer> s1=new HashSet<Integer>();
s1.add(6);
List<Integer> l=new ArrayList<Integer>();
l.add(5);
l.add(2,2);
l.add(0);
System.out.println(l);
S.addAll(l);//list
S.addAll(s1);//another set

Related

Create a List of unique values in java

I have data of which the sequence is as important as its unique elements. Meaning if something has already been added it should not be added again and the sequence must be remembered.
Set does not remember the sequence in which it was added (either hash or sort), and List is not unique.
What is the best solution to this problem?
Should one have a list and loop through it to test for uniqueness - which I'm trying to avoid?
Or should one have two collections, one a List and one a Set - which I'm also trying to avoid?
Or is there a different solution to this problem altogether.
In the bellow code was your reference
LinkedHashSet<String> al=new LinkedHashSet<String>();
al.add("guru");
al.add("karthik");
al.add("raja");
al.add("karthik");
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
output
guru
karthik
raja
Use LinkedHashSet. It serves as both a List and a Set. It has the uniqueness quality of a set but still remembers the order in which you inserted items to it which allows you to iterate it by order of insertion.
From the Docs:
Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set. (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)
You can use SortedSet
or LinkedHashSet
LinkedHashSet is the best possible way out

Why set <Integer> is sorting added values?

When I start to add value into Set<Integer> I get sorting elements.
Please refer to this example:
Set<Integer> generated = new HashSet<Integer>();
generated.add(2);
generated.add(1);
generated.add(0);
Here I get sorting Set [0, 1, 2]. I would like to get value as I add to generated object.
A HashSet does not have a predictable order for elements. Use a LinkedHashSet to preserve insertion order of elements in a set:
Hash table and linked list implementation of the Set interface, with predictable iteration order.
Set<Integer> generated = new LinkedHashSet<Integer>();
generated.add(2);
generated.add(1);
generated.add(0);
Firstly it's just a co-incidence that you get sorted value first time. If you run that code multiple time, you'll see the output in some random order. That's because a HashSet doesn't enforce any ordering on elements you add.
Now to get the elements in the order you inserted, you can use LinkedHashSet, that maintains the insertion order.
The HashSet does not guarantee the order of the elements. From the JavaDoc:
It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
So, in order to keep guarantee the order a LinkedHashSet can be used. From the JavaDoc:
Hash table and linked list implementation of the Set interface, with predictable iteration order.
This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order).
Simply instantiate your Set like this:
Set<Integer> generated = new LinkedHashSet<>();
First, regarding the title of your question, Set<Integer> is only the declaration type and its not responsible of any sorting / unsorting behavior, the main reason for using the Set interface is when caring about uniqueness — it doesn't allow duplicates, additional informations from Javadocs:
A Set is a Collection that cannot contain duplicate elements.
Second, it's pure concidence that you got sorted set, use HashSet when you don't care about order when iterating through it, more infos from javadocs:
It makes no guarantees as to the iteration order of the set; in
particular, it does not guarantee that the order will remain constant
over time. This class permits the null element.
Third, regarding what you are looking for:
I would like to get value as I add to generated object.
then you need to use LinkedHashSet which takes care of the order in which elements were inserted, again from javadocs:
This linked list defines the iteration ordering, which is the order in
which elements were inserted into the set (insertion-order). Note that
insertion order is not affected if an element is re-inserted into the
set
you may use it simply like this:
Set<Integer> generated = new LinkedHashSet<Integer>();
Fourth and Last, as additional information, another important collection that you need to be aware of it, is the TreeSetwhich guarantees that the elements will be sorted in ascending order, according to natural order, javadocs:
The elements are ordered using their natural ordering, or by a
Comparator provided at set creation time, depending on which
constructor is used

Will getting the first item from the iterator of a set return a random value?

I'm using Set#iterator().next(); all by itself, and I'm wondering if:
A) Will that cause memory leaks, or at least any kind of avoidable overhead,
and
B) Whether or not item it returns will be a random item, and if I use this method multiple times, it'll give a different item every time?
Iterator<E> iterator()
Returns an iterator over the elements in this set. The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee).
http://docs.oracle.com/javase/7/docs/api/java/util/Set.html#iterator()
If you need to get the elements in the same order every time you iterate through the Set, try one of these specific implementations that guarantee order:
TreeSet: sorts elements based on their value (natural order)
ConcurrentSkipListSet: sorts elements based on their value (natural order)
LinkedHashSet: sorts elements based on the order they were inserted in the set (insertion order)
The first two implement the SortedSet interface.
From the docs of Iterator#next()
Returns the next element in the iteration.
Which means that it'll return the items in the order they are stored in the Set. And regarding the different item, Yes, it'll return next(different) item always(till there are more items remaining in the Set) and will terminate(by throwing the NoSuchElementException) once it has exhausted all of them.

HashSet getting sorted

I am getting the unique elements from a arraylist into a hashset but it is being sorted by itself.But i need the data not to be in sorted order.How can it be done?
HashSet getting sorted
The items of a HashSet is not in a particular order at all, as explicitly stated in its javadoc:
It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
Perhaps you meant to say that the items are "rearranged" in a different order than you have added the items and that this is undesireable.
In that case, just use LinkedHashSet instead of HashSet. It maintains the elements in insertion order.
Set<T> unique = new LinkedHashSet<T>(arrayList);
Or, perhaps, if you prefer automatic ordering based on the element's Comparable#compareTo() implementation or would like to supply a custom Comparator, then use a TreeSet instead.
Set<T> uniqueAndSorted = new TreeSet<T>(arrayList);
See also:
The Java Tutorials - Collecitons - Implementations
What do yo mean by 'I want data not in sorted order'? Do you mean to say that you want the same order in which it is present in the list?
If so, you can create a LinkedHashSet and add the entries from the arraylist.
eg:
ArrayList list = new ArrayList();
LinkedHashSet set = new LinkedHashSet();
for (String temp : list) {
set.add(temp);
}
This will ensure the same order in which the elements are present in the arraylist.

Array List retrieval order

I have a java ArrayList to which I add 5 objects.
If I iterate over the list and print them out, then iterate over the list and print them out again.
Will the retrieval order in these 2 cases be the same? (I know it may be different from the insertion order)
Yes, assuming you haven't modified the list in-between. From http://docs.oracle.com/javase/6/docs/api/java/util/List.html:
iterator
Iterator<E> iterator()
Returns an iterator over the elements in this list in proper sequence.
A bit vague, perhaps, but in other portions of that page, this term is defined:
proper sequence (from first to last element)
(I know it may be different from the insertion order)
No it won't. The contract of List requires that the add order is the same as the iteration order, since add inserts at the end, and iterator produces an iterator that iterates from start to end in order.
Set doesn't require this, so you may be confusing the contract of Set and List regarding iteration order.
From the Javadoc:
Iterator<E> iterator()
Returns an iterator over the elements in this list in proper sequence.
It's in the specification of the List interface to preserve order.
It's the Set classes that don't preserve order.
If you're not mutating the list, then the iteration order will stay the same. Lists have a contractually specified ordering, and the iterator specification guarantees that it iterates over elements in that order.
Yes, an ArrayList guarantees iteration order over its elements - that is, they will come out in the same order you inserted them, provided that you don't make any insertions while iterating over the ArrayList.
Retrieval does not vary unless you change the iterator you are using. As long as you are using the same method for retrieval and have not changed the list itself then the items will be returned in the same order.
When you add an element to an ArrayList using add(E e), the element is appended to the end of the list. Consequently, if all you do is call the single-argument add method a number of times and then iterate, the iteration will be in exactly the same order as the calls to add.
The iteration order will be the same everytime you iterate over the same unmodified list.
Also, assuming you add the elements using the add() method, the iteration order will be the same as the insertion order since this method appends elements to the end of the list.
Yes the retrieval order is guaranteed to be the same as long as list is not mutated and you use the same iterator, but having to need to rely on retrieval order indicated something fishy with the design. It is generally not a good idea to base business logic upon certain retrieval order.
Even Sets will return the same result, if you don't modify them (adding or removing items to them).

Categories

Resources