Suppose there is a string treeset (ts)of elemnent 1,2,3,4,5,6,7,8,9,10.
Is there is any in built method in treeset so that i can access an element.
For eg accessing 3 can i do ts.[2]and accessing 8 ts.[7].(something like that).
i used this method:
Iterator<String> it = ts.iterator();
int i=0;
while(it.hasNext()) {
String ele=it.next();
if(i==2){
System.out.println(ele+"");
}
i++;
}
though when i ran it didn't showed any o/p but if i did i=0 then it showed all the o/p i.e 1,2,3,4,5,6,7,8,9,10.
Secondly can anyone tell me that when it is best to use hashset,treeset and linkedhashset
If you wanna access elements in your collection like ts[2], then you should better convert your collection into array using collection inbuilt method.
Otherwise, using iterator is the standard and efficient way to access elements in collection.
For second question, Hashset is used as hash table ; LinkedHashSet is used as hash table with elements stored in same way as inserted; TreeSet is used for collection using navigations.
For complete knowledge you must check Oracle documentation.
TreeSet is a NavigableSetwhich means you have an order of items (natural ordering as default, but you can define your own ordering relationship by using Comparator or Comparable interface) and you can navigate through items by this order. However there is no index mechanism. Basically a TreeSet is based on a TreeMap which is a red-black tree. In such a data structure indexes (element indexes, not indexes in the sense of efficient access) are not much meaningfull.
HashSet on the other hand is based on a HashMap which is a classical hash table implementation. In this data structure there is no order defined. You can look up each item at O(1) time though due to hash function used.
LinkedHashSet is a subclass of HashSet. Other then HashSet methods no new method is defined, so LinkedHashSet does not allow any more capability like natural order or indexes. However it has an auxilary linked list that keeps track of the order in which elements are inserted. In this way when you iterate over a LinkedHashSet by .iterator() method or a for loop you get elements in the order you inserted.
So basically a HashSet is more appropriate if you will access elements individually. Or being the simplest Set implementation you can use HashSet in generic cases. If you need to keep the order of insertion you need to use LinkedHashSet and if you have to enforce any custom ordering or natural ordering of items you should use TreeSet.
Related
Please explain how different collection are used under different scenario.
By this I mean to say how can I differentiate when to use a List, a Set or a Map interface.
Please provide some links to examples that can provide a clear explanation.
Also
if insertion order is preserved then we should go for List.
if insertion order is not preserved then we should go for Set.
What does "insertion order is preserved" means?
Insertion order
Insertion order is preserving the order in which you have inserted the data.
For example you have inserted data {1,2,3,4,5}
Set returns something like {2,3,1,4,5}
while list returns {1,2,3,4,5} .//It preserves the order of insertion
When to use List, Set and Map in Java
1) If you need to access elements frequently by using index, then List is a way to go. Its implementation e.g. ArrayList provides faster access if you know index.
2) If you want to store elements and want them to maintain an order on which they are inserted into collection then go for List again, as List is an ordered collection and maintain insertion order.
3) If you want to create collection of unique elements and don't want any duplicate then choose any Set implementation e.g. HashSet, LinkedHashSet or TreeSet. All Set implementation follow there general contract e.g. uniqueness but also add addition feature e.g. TreeSet is a SortedSet and elements stored on TreeSet can be sorted by using Comparator or Comparable in Java. LinkedHashSet also maintains insertion order.
4) If you store data in form of key and value then Map is the way to go. You can choose from Hashtable, HashMap, TreeMap based upon your subsequent need.
You will find some more useful info at http://java67.blogspot.com/2013/01/difference-between-set-list-and-map-in-java.html
I am wondering if there is a more efficient method for getting objects out of my LinkedHashMap with timestamps greater than a specified time. I.e. something better than the following:
Iterator<Foo> it = foo_map.values().iterator();
Foo foo;
while(it.hasNext()){
foo = it.next();
if(foo.get_timestamp() < minStamp) continue;
break;
}
In my implementation, each of my objects has essentially three values: an "id," "timestamp," and "data." The objects are insterted in order of their timestamps, so when I call an iterator over the set, I get ordered results (as required by the linked hashmap contract). The map is keyed to the object's id, so I can quickly lookup them up by id.
When I look them up by a timestamp condition, however, I get an iterator with sorted results. This is an improvement over a generic hashmap, but I still need to iterate sequentially over much of the range until I find the next entry with a higher timestamp than the specified one.
Since the results are already sorted, is there any algorithm I can pass the iterator (or collection to), that can search it faster than sequential? If I went with a treemap as an alternative, would it offer overall speed advantages, or is it doing essentially the same thing in the background? Since the collection is sorted by insertion order already, I'm thinking tree map has a lot more overhead I don't need?
There is no faster way ... if you just use a LinkedHashMap.
If you want faster access, you need to use a different data structure. For example, a TreeSet with an appropriate comparator might be a better solution for this aspect of your problem. For example if your TreeSet is ordered by date, then calling tailSet with an appropriate dummy value can give you all elements greater or equal to a given date.
Since the results are already sorted, is there any algorithm I can pass the iterator (or collection to), that can search it faster than sequential?
Not for a LinkedHashMap.
However, if the ordered list was an ArrayList instead, then you could use "binary search" on the list ... provided that you could lock it to prevent concurrent modifications while you are searching. (Actually, concurrency is a potential issue to consider no matter how you implement this ... including your current linear search.)
If you want to keep the ability to do id lookups, then you need two data structures; e.g. a TreeSet and a HashMap which share their element objects. A TreeSet will probably be more efficient than trying to maintain an ArrayList in order assuming that there are random insertions and/or random deletions.
I've sorted an arraylist of int in ascending order, but when I copy it in a set, the elements are not sorted anymore.
I'm using this :
HashSet<Integer> set = new HashSet<Integer>(sortedArray);
why is like that?
LinkedHashSet will keep the order. TreeSet will sort based either on an external Comparator or natural ordering through Comparable.
A general point of a Set is that order is irrelevant. Hashing is intended to put the elements in as random an order as possible. LinkedHashSet maintains a linked-list between references to the elements, so can maintain an order.
BitSet (which is not a Set) may, or may not, provide a more efficient data structure.
HashSet's don't sort or maintain order, and the API will tell you this:
it does not guarantee that the order will remain constant over time.
Consider using another type of Set such as a TreeSet.
If you just care about uniqueness, use the HashSet. If you're after sorting, then consider the TreeSet.
you need to use TreeSet and implement a Comparator object or Comparable interface for your data. you can read about Object ordering here
hash set is designed for quick access to unique data, not for maintaining a particular order.
I have a collection of a big number of objects that are defined by name/value pairs.
I need to have fast access to any of their values and to be able to return them ordered alphabetically by name. First I thought I might use a HashMap to get fast access. But it gave me no ordering. I decided to switch to LinkedHashSet.
The problem with it is that I need to be able to insert new Objects in the right places of the list, but LinkedHashSet doesn't allow that. I also need to be able to access Objects by their index as well as by name.
Will be thankful for any ideas.
Why not try TreeSet. Does your list not allow duplicates? If so then the Set should be ok. As you are adding strings and this implements Comparator the set will be automatically sorted for you
If you had
Set<String> s = new TreeSet<String>();
s.add("B");
s.add("C");
s.add("A");
then the contents of the set would be A, B, C
You can use TreeMap
A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
I would use a TreeSet which is a SortedSet. You need to define your custom class as Comparable based on the name and your collection will always be sorted.
Note: sorted collections have an O(log N) access time.
Have you looked at TreeMap? It's based off of Red-Black trees which help maintain ordering, but still gives fast access.
A TreeMap should address your requirements. If your keys are not literals then use appropriate Comparator in TreeMap constructor.
Does such a thing exist anywhere? Basically I see java has LinkedHashSet but no type of navigatable hash set?
By its very nature, a hash-based data structure is not ordered. You can write wrappers which supplement it with an additional data structure (this is more or less what LinkedHashMap does). But while it makes some sense to keep a hash set and a list, in order to keep a good ordering, you would need a tree or similar data structure. But the tree can work as a set by itself, so you would essentially be duplicating the information (more than in the case of set plus list, which differ more than two different set implemnentations). So the best solution is to just use TreeSet or another SortedSet if you need order.
It's not a HashSet, but as a descendant of Set you have the TreeSet
This class implements the Set interface, backed by a TreeMap instance. This class guarantees that the sorted set will be in ascending element order
You can traverse the elements using the iterator
public Iterator iterator()
Returns an iterator over the elements in this set. The elements are returned in ascending order
You can use a TreeSet but all the operations in it are lg(n)
You can use a LinkedHashSet, which keeps a linked list on top of hashset, but it only maintains insertion ordering (first inserted will be first element in iterator), you cannot have natural or custom ordering
You could also use TreeSet+HashSet approach but two reference for each element will be kept and while add and remove would still be lg(n) the contains will become expected o(n)
choose wisely :)
I guess there's TreeMap which is...related but definitely not the same :)