Reputation: 1155
Hello I am trying to avoid creating object by using normal array to store 2 key value, but it does not seems to work.
May I know is there any solution to avoid that one object creation or am I just trying too hard?
Forgotten to ADD:
1) I know why it does not work... I won't be implementing the equals() and hashcode() for key if I don't.
2) Basically I am trying to avoid 1 object creation when retrieving the key. Usually in the service class there will be a method
public void get(String key1, String key2){
return keyMap.get(new Key(key1,key2)); <>>avoiding the new Key()
}
BREAK LINE
import java.util.HashMap;
import java.util.Map;
public class ArrayMap {
/**
* @param args
*/
public static void main(String[] args) {
/*start A Possible to get this to work? */
Map<String[], String> arrMap = new HashMap<>();
arrMap.put(new String[] { "hello", "hi" }, "hello motto");
System.out.println(arrMap);
System.out.println(arrMap.get(new String[] { "hello", "hi" })); // print
// null
/* end of A */
/*Start of B: Reason: to avoid this */
Map<Key, String> keyMap = new HashMap<Key, String>();
keyMap.put(new Key("hello", "hi"), "hello motto"); // I wish to avoid one object creation
System.out.println(keyMap.get(new Key("hello", "hi"))); // print
// "hello motto"
/*End of B: Reason: to avoid this */
}
}
class Key {
private final String key1;
private final String key2;
public Key(String key1, String key2) {
this.key1 = key1;
this.key2 = key2;
}
public String getKey1() {
return key1;
}
public String getKey2() {
return key2;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key1 == null) ? 0 : key1.hashCode());
result = prime * result + ((key2 == null) ? 0 : key2.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Key other = (Key) obj;
if (key1 == null) {
if (other.key1 != null)
return false;
} else if (!key1.equals(other.key1))
return false;
if (key2 == null) {
if (other.key2 != null)
return false;
} else if (!key2.equals(other.key2))
return false;
return true;
}
}
Upvotes: 1
Views: 351
Reputation: 4569
There are a couple of problems with this approach.
1. You can't override the equals()
/hashcode()
methods for arrays - This is an issue because the HashMap
won't be able to correctly determine whether it has looked up the right key or not.
2. You're still creating new objects every time you want to create a key. Arrays are objects - you save nothing by creating a new one every time. Might as well use your original Key
object.
Possible Solution
So I'm going to assume the reason why you want to avoid creating a new object every time is because you're going to be calling get(key)
on that HashMap
a LOT. If that's the case, why not create a mutable Key
instance that remains internal to your ArrayMap
object. Every time you want to key on two String
s, simply set them in your mutable Key
instance and use that mutable instance for the lookup. Then you don't create a new Key
every time you want to look up a value for a pair of Strings
.
Upvotes: 4
Reputation: 500357
May I know is there any solution to avoid that one object creation or am I just trying too hard?
If you are unsure whether you're trying too hard, then you probably are. Based on the information you've given us, this looks like premature optimization.
A couple of pertinent points:
Upvotes: 2
Reputation: 591
In java, array1.equals(array2) only if array1 == array2, i.e. they are the same exact instance in memory. So that causes the Map to view them as separate keys. You're better off going with your Key class for the map's key
Upvotes: 1
Reputation: 279970
In these lines
arrMap.put(new String[] { "hello", "hi" }, "hello motto");
System.out.println(arrMap);
System.out.println(arrMap.get(new String[] { "hello", "hi" })); // print
// null
you use a String[]
as a key. That object doesn't have a custom equals()
method like the one you have in your Key
class where you can compare the contents. So when you try to do map.get()
passing in a new String[]
(but with the same content), it won't find anything because it's not the same object.
What you might want to do is this
String[] array = new String[] { "hello", "hi" };
arrMap.put(array , "hello motto");
System.out.println(arrMap);
System.out.println(arrMap.get(array)); // print hello motto
You really shouldn't use array types as keys to Maps.
Upvotes: 2