Shekhar Gulati is a Java Consultant with over 5 years experience.He is currently working with Xebia India an Agile Software Development company.The postings on this site and on his blog are his own and do not necessarily represent opinion of his employer. His own blog is at http://whyjava.wordpress.com/ and you can follow him on twitter here. Shekhar has posted 25 posts at DZone. View Full User Profile

Java Puzzler on Arrays

08.06.2010
| 8604 views |
  • submit to reddit

Today, while working with arrays I came accross a Java puzzle which made me wonder WHY IS THIS PIECE OF CODE NOT WORKING?

Java Puzzle

Can you guess whether this Junit test case will pass?

@Test
public void testMapOfArray() {

Map<String[], String[]> map = new HashMap<String[], String[]>();
map.put(new String[] { "shekhar" },
new String[] { "I am Java Developer" });
map.put(new String[] { "rahul" }, new String[] { "I am C# Developer" });

String[] description = map.get(new String[] { "shekhar" });
assertThat(description[0], IsEqual.equalTo("I am Java Developer"));
}


Everytime I ran this test it failed with NullPointerException.

What's the reason for this unexpected behavior?

The problem is that String[] uses object identity for equals and hashcode methodsz. So,

String[] arr1 = new String[] { "shekhar" };
String[] arr2 = new String[] { "shekhar" };

 will not match with eachother in a HashMap. 

Advice
Don't use arrays as HashMap keys. If you want to use an array as a key, then write a wrapper arround an array and override equals and the hashcode method.

 

 

2.5
Your rating: None Average: 2.5 (4 votes)
Published at DZone with permission of its author, Shekhar Gulati.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Eric Jablow replied on Fri, 2010/08/06 - 4:41pm

More to the point, never use mutable objects as keys of HashMaps or elements of HashSets. Arrays are always mutable. Sadly, so are Dates. As a horrible example, take a typical Name JavaBean class with givenName and surName members and the obvious getters, setters, and equals, and hashCode methods.
HashMap<Name, Integer> ages = new HashMap<Name, Integer>();
Name me = new Name("Eric", "Jablow");
ageMap.put(me, 48);
me.setGivenName("Ricky");
System.out.println(ages.get(me)); // Probably prints null.
Why? Because it will look in the wrong hash bucket.

Marco Rietveld replied on Fri, 2010/08/06 - 4:45pm

First there was a String constant pool.. and then a Long, and an Integer and probably even a Double constant pool, et cetera. 

But there has never been an "array" constant pool because 1. Array's can't be autoboxed and 2.  Even if you could, why would you autobox a collection? It's the content of the collection that counts! 

 

Chad Retz replied on Fri, 2010/08/06 - 5:35pm

Um...I think it's pretty commonly known that

new String[] { "bob" }.hashCode() != new String[] { "bob" }.hashCode()

Just use eclipse's auto-generated hashCode and equals on a POJO containing your array and it will be fine (Arrays.hashCode, Arrays.equals, etc). Or just use a List or Set as your key which guarantee the equals and hashCode on common elements

Thomas J. Clancy replied on Sat, 2010/08/07 - 12:17pm

Who would do this anyway?

Cosmin Mutu replied on Mon, 2010/08/09 - 12:48am

who said SCJP exams are worthless? :)

Pradeep Arumalla replied on Mon, 2010/08/09 - 10:22am


     Try the below code,when ever you do a "new Somthing()", is a new object 

 

Map<String[], String[]> map = new HashMap<String[], String[]>();
      
      String[] key=new String[] { "shekhar" };
      map.put(key,
              new String[] { "I am Java Developer" });
      map.put(new String[] { "rahul" }, new String[] { "I am C# Developer" });

      String[] description = map.get(key);
      //assertThat(description[0], "I am Java Developer".equals("I am Java Developer"));
    
      System.out.println(description[0].toString());

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.