-1

Property of SET is it doesnt allow duplicate elements .

but referring to SCJP: When hashset or linkedhashset is used. when you add objects you must override hashcode else you may end up with duplicate elements in the set.

boolean[] b=new boolean[5];
Set s=new HashSet();
b[0]=s.add("a");
b[1]=s.add("a");

here the output is True , False I wonder how come the output is false when you have not overridden the hashcode. But when you override hashcode, you must overrride equals().

DOes Collection interface provide default equals() method?

I am not able to understand,

5 Answers5

3

You're adding two java.lang.String's for which class Sun/Oracle have already supplied fitting .hashCode() and .equals() methods for you :-)

Note: It's not the collections that need the equals and hash methods - it's the objects you put into them!

If you were to add YourOwnClass objects to a JDK collection, you must override both these methods sensibly. Consider this, where YourOwnClass falls back to java.lang.Object's implementations of the methods in point:

class YourOwnClass
{
    String a;
    public YourOwnClass(String a) { this.a = a; }
}

public void testYourOwnClass() throws Exception
{
    Set<YourOwnClass> set = new HashSet<YourOwnClass>();

    System.out.println( set.add( new YourOwnClass( "b" ) ) );
    System.out.println( set.add( new YourOwnClass( "b" ) ) );
}

This will print

true

true

even though we could argue that the two YourOwnClass objects added should probably be considered identical from a semantic viewpoint.

Then, modify YourOwnClass as follows, and try again.

class YourOwnClass
{
    String a;
    public YourOwnClass(String a) { this.a = a; }

    @Override public int hashCode() { return a.hashCode(); }
    @Override public boolean equals(Object obj) { return a.equals( ((YourOwnClass)obj).a ); }
}

Voila - "true false" this time!

Cheers,

Community
  • 1
  • 1
Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
  • referring to SCJP: When hashset or linkedhashset is used. when you add objects you must override hashcode else you may end up with duplicate elements in the set. What does this mean? Can you give a fitting explaination – Sagar Byali Nov 13 '14 at 14:04
  • It means that the objects you add must have a meaningful implementation of equals() and hashCode() - these methods must return true and the same value respectively for objects that YOU consider to be equal. See the additions to my answer for an example. – Anders R. Bystrup Nov 13 '14 at 14:19
2

Ok.. To start off.

When hashset or linkedhashset is used. LinkedhashSet maintains order of inserted elements, HashSet doesnt.

I wonder how come the output is false The add() method returns true if the element is added (when the element is not already present in the set.So, in your case, first time around, "a" is not present in the set), so it returns true the first time around. the second time, "a" will already be present so, it will return false.

Next, by default, all objects have hashCode() and equals() implementations. You have to override them to change the default behaviour.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
1

Does Collection interface provide default equals() method?

Yes by default hashCode() method is used in equals() that is defined in Object class itself

For some classes such as String the equals() checks for characters for equality.

Check the source code of String.equals() method


If item is already added in Set then it returns false otherwise returns true as mentioned in Java Doc as well.

Braj
  • 46,415
  • 5
  • 60
  • 76
  • I know Strings,Date,Calender,Wrappers have default hashcode and equals. But my question is: Does hashset and linkedhashset also come under the same bracket(since they extend from Collection) (Strings,Date,Calender,Wrappers,Hashset,Linkedhashset). But map doesnt inhert from colection – Sagar Byali Nov 13 '14 at 13:46
  • Your question is not clear to me. It depends on the object that you are adding in collection. It uses `equals()` and `hashCode()` of the item that is added. – Braj Nov 13 '14 at 13:47
  • Is your question why override `equals()` when `hashCode()` is overridden? – Braj Nov 13 '14 at 13:50
  • if u add string object or wrapper object (they already have hashcode and eqauls) but if you add a primitive: boolean[] b=new boolean[5]; Set s=new HashSet(); b[0]=s.add(2); b[1]=s.add(2);//Will the output be True and True? – Sagar Byali Nov 13 '14 at 13:51
  • No It will be `True` then `False` – Braj Nov 13 '14 at 13:52
  • HAshcode and equals rule: if equals method returns true ..it means that hashcode being true is a must....if hashcode returns false then equals can never return true – Sagar Byali Nov 13 '14 at 13:52
  • " If hashCode returns false then equals can return true as well" This means you have not overridden hashcode() right. so even if two objects are equal. They will fall into their own bucket and unable to compare – Sagar Byali Nov 13 '14 at 13:56
0

First of all, String does override hashCode and equals, so your code uses String's version of those methods (since you are adding Strings to your HashSet).

Second of all, even if it didn't, in your example, "a" is interned, so both calls to s.add("a") are adding the exact same object, so even Object's default implementation of hashCode and equals would have given the same results.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • boolean[] b=new boolean[5]; Set s=new HashSet(); b[0]=s.add(new Integer(2)); b[1]=s.add(new Integer(2));//What will be the output? – Sagar Byali Nov 13 '14 at 13:44
  • @SagarByali Integer also overrides hashCode and equals. – Eran Nov 13 '14 at 13:45
  • boolean[] b=new boolean[5]; Set s=new HashSet(); b[0]=s.add(2); b[1]=s.add(2);//What will be the output? – Sagar Byali Nov 13 '14 at 13:57
  • @SagarByali true and false. int would be boxed to Integer, so the behavior would be identical to your previous comment. – Eran Nov 13 '14 at 14:00
  • Is their any way, we can make this return as TRUE and TRUE ? – Sagar Byali Nov 13 '14 at 14:01
  • @SagarByali create your own class, for example Person (having first and last name), don't override equals and hashCode, then call twice s.add(new Person("John","Smith"));. The two instances would be considered distinct, since the default implementation of Object.hashCode and Object.equals would be used. – Eran Nov 13 '14 at 14:04
0

First thing first - I completely agree and +1 @TheLostMind answer above regarding LinkedHashset. Also, you probably are lacking the understanding of what .add() method is actually returning i.e. what does it check before returning you with a boolean result.

P.S. It's one of the standards in JavaBeans that you should override hashcode() and equals() to avoid erroneous results - see http://www.xyzws.com/javafaq/why-always-override-hashcode-if-overriding-equals/20

Remember that you are using HashSet and for HashSet the equals() and hashCode() methods are inherited from AbstractSet. AbstractSet is an abstract class and HashSet extends it and there is no requirement to implement any abstract methods. Because the equals() and hashCode() are implemented already, the result you see for the code below comes as true and false. I have separated them using scope {} operator to improve clarity.

public static void main (String[] args) throws java.lang.Exception
{

{   boolean[] b = new boolean[5]; 
    Set s = new HashSet(); 
    b[0]=s.add(new Integer(2)); 
    b[1]=s.add(new Integer(2));

    System.out.println("Using Hashset Integers b0 = "+b[0]+" and b1 = "+b[1]);
}

{   
    boolean[] b=new boolean[5]; 
    Set s=new HashSet(); 
    b[0]=s.add(2); 
    b[1]=s.add(2);
    System.out.println("Using Hashset int b0 = "+b[0]+" and b1 = "+b[1]);
}   


}

I believe for int and Integer hashCode() and equals() are alrady sorted out by Java. You don't need to worry about that. I implemented a dataserver using Spring Framework where I needed my own entity class and to make sure that I could save my Entity bean objects into a HashMap I had to override equals() and hashCode() in my Entity definition class. If you use Eclipse, you can use autogenerator to give you a skeleton of hashCode() and equals() which then can be edited to suit your needs.

ha9u63a7
  • 6,233
  • 16
  • 73
  • 108
  • boolean[] b=new boolean[5]; Set s=new HashSet(); b[0]=s.add(new Integer(2)); b[1]=s.add(new Integer(2));//What will be the output? and boolean[] b=new boolean[5]; Set s=new HashSet(); b[0]=s.add(2); b[1]=s.add(2);//What will be the output? – Sagar Byali Nov 13 '14 at 13:58
  • @SagarByali It will true false - and true false. See here - http://ideone.com/cJTlRL – ha9u63a7 Nov 13 '14 at 14:09