I am not able to use hashset in my scenario. Because there is no functionality of retrieving the object if the HashSet contains it.
My implementation of HashSet is such that the 'equals()' checks only for a certain property of the object. The other properties may vary. So, if an object contains() the object that I am searching for, i.e if the particular property matches, I want to retrieve the object and compare the other properties. But there is not function to retrieve the object, only a function to remove it is there.
Is there any altervative to it that can suit my requirements?
You can use hash map instead eq HashMap<Your_Class, Your_Class> which has get method
You might also consider Interner pattern. There are libraries that already have it.
Guava version is thread-safe which is probably bad for performance...
Related
As we all known, in Sun(Oracle) JDK, HashSet is implemented backed by a HashMap, to reuse the complicated algorithm and data structure.
But, is it possible to implement a MyHashMap using java.util.HashSet as its back?
If possible, how? If not, why?
Please note that this question is only a discussion of coding skill, not applicable for production scenarios.
Trove bases it's Map on it's Set implementation. However, it has one critical method which is missing from Set which is a get() method.
Without a get(Element) method, HashSet you cannot perform a lookup which is a key function of a Map. (pardon the pun) The only option Set has is a contains which could be hacked to perform a get() but it would not be ideal.
You can have;
a Set where the Entry is a key and a value.
you define entries as being equal when the keys are the same.
you hack the equals() method so when there is a match, that on a "put" the value portion of an entry is updated, and on a "get" the value portion is copied.
Set could have been designed to be extended as Map, but it wasn't and it wouldn't be a good idea to use HashSet or the existing Set implementations to create a Map.
I am looking for a way to determine if a Collection (or maybe even any Iterable) is guaranteed to be ordered by its class contract.
I already know the Guava method : Ordering.natural().isOrdered(myCollection)
But this method is not relevant to my needs, because it checks if the values inside the collection are ordered. That's not what I need to determine, what I want to have is a isSorted method that will behave like this :
isSorted(new HashSet()) -> false
isSorted(new ArrayList()) -> true
etc...
What I am looking at would be typically implemented by checking the class of the collection, and comparing it to some kind of reference table of the collections which contract states that they are ordered, and only return true for these ones.
Do you know if something like this already exists in some library ?
You can do the following to determine if a collection is defined to be sorted.
collection instanceof SortedSet
There are three interfaces for ordered collections: List, SortedSet and SortedMap. You can check if your class is implementing one of them.
No, this doesn't exist in any library, and for good reason.
That library would have to know all the collection types that are flying around. If you're using Apache Commons Collections, it'd have to know about all of those. If you're using Guava, it'd have to know about all of those. If someone comes along and introduces a new collection type, you're now going to reject that type, even if it's ordered.
It doesn't make sense to provide that method in a library that can't know what other libraries you might have with whatever other collection types might be out there.
In an end application, it might make sense to implement it, with the heuristic techniques you've already been describing.
It might help if we knew what you were actually trying to do with this method.
It is obvious that immutability increases the re-usability since it creates new object in each state change.Can somebody tells me a practical scenario where we need a immutable class ?
Consider java.lang.String. If it weren't immutable, every time you ever have a string you want to be confident wouldn't change underneath you, you'd have to create a copy.
Another example is collections: it's nice to be able to accept or return a genuinely immutable collection (e.g. from Guava - not just an immutable view on a mutable collection) and have confidence that it won't be changed.
Whether those count as "needs" or not, I don't know - but I wouldn't want to develop without them.
A good example is related to hashing. A class overrides the equals() and hashCode() methods so that it can be used in data structures like HashSet and (as keys in) HashMap, and the hash code is typically derived by some identifying member attributes. However, if these attributes were to change then so would the object's hash code, so the object is no longer usable in a hashing data structure.
Java provides a nice example: String.
This article has a good color example (since color definitions don't change).
http://www.ibm.com/developerworks/java/library/j-jtp02183/index.html
In my implementation, I have a class A which overrides equals(Object) and hashCode(). But I have a small doubt that is, while adding the instance of A to HashSet/HashMap the value of the hashCode() is x, after sometime the value of the same hashCode() changed to y. Will it effect anything?
The hash code mustn't change after it's been added to a map / set. It's okay for it to change before that, although it generally makes the type easier to work with if it doesn't change.
If the hash code changes, the key won't be found in the map / set, as even if it ends up in the same bucket, the hash code will be changed first.
When the return value of hashCode() or equals() changes while the object is contained in HashMap/HashSet etc., the behavior is undefined (you could get all kinds of strange behavior). So one must avoid such mutation of keys while the object is contained in such collections etc.
It is considered best to use only immutable objects for keys (or place them in a HashSet etc.). In fact python for example, does not allow mutable objects to be used as keys in maps. It is permissive/common to use mutable objects as keys in Java, but in such case it is advisable to make such objects "effectively immutable". I.e. do not change the state of such objects at all after instantiation.
To give an example, using a list as a key in a Map is usually considered okay, but you should avoid mutating such lists at any point of your application to avoid getting bitten by nasty bugs.
As long as you don't change the return value of hashCode() and equals() while the objects are in the container, you should be ok on paper. But one could easily introduce nasty, hard to find bugs by mistake so it's better to avoid the situation altogether.
Yes, the hash code of an object must not change during its lifetime. If it does, you need to notify the container (if that's possible); otherwise you will can get wrong results.
Edit: As pointed out, it depends on the container. Obviously, if the container never uses your hashCode or equals methods, nothing will go wrong. But as soon as it tries to compare things for equality (all maps and sets), you'll get yourself in trouble.
Yes. Many people answered the question here, I just want to say an analogy. Hash code is something like address in hash-based collection:
Imagine you check in a hotel by your name "Mike", after that you change your name to "GreatMike" on check-paper. Then when someone looks for you by your name "Mike", he cannot find you anymore.
We find a lot of concrete subclasses under Collection.
While trying to add an element in a concrete collection, this collection will use a method to determine if it can accept to store the element (and eventually that this element is not already in the collection).
It could use equals(), hashCode() or compareTo() of the element.
Is it possible to find a summary about which method is used by each implementation of Collection ?
Thanks a lot for your answers.
First of all not all collections check whether the element you're adding already exists in the collection. For example ArrayList just appends the element to the tail of the list, without checking if it's already in the list. Other classes use equals if the collection is guaranteed to have only one copy of the object, or compareTo, if the elements are supposed to be Comparable and the collection is sorted (to find the right place to insert it at). Maps will also use equals to check for the key, but some like HashMap will also use hashCode() to speed up the searching process (they first get all keys with the same hashcode, and then use equals on each of them to find if the key already exists and has a value assigned, which will then get replaced).
But if you want to see how they work you can check out the sources that are included with the jdk.
In eclipse I have the JRE set to the folder where the jdk is installed, and I can use CTRL+SHIFT+T to open any class (type) in the jdk, CTRL+click the name of a class, or for methods, even CTRL+click -> open implementation, which opens a pop up with the classes the implement that method (if it's from an interface, or the method directly in the class, if it's not)
Any concrete implementation should indicate in its API doc what assumptions it makes about the behaviour of its elements.
Generally, hash based collections use hashCode() and tree based ones use compareTo() or a Comparator, and all of them use equals().