This question already has answers here:
What happens if two different objects have the same hashcode?
(5 answers)
Closed 4 years ago.
I have a Hashtable to find objects by number. Let's assume I do
Hashtable<Integer, MyClass> table = ...
table.put(10, myObject);
and query this with a byte or Byte object that also has value 10, then I get no result.
Byte b = new Byte(10);
table.get(b); // -> null
table.get((int)b); // -> myObject
table.get(10); // -> myObject
table.get((byte)10); // -> null
Byte and Integer objects are different, I know. But it compiles and both have the same hashcode, namely the value 10. Shouldn't both find the object?
The byte value on one of my cases is unchangeable. I can cast it to int but I would like to understand what's going on here.
Edit: Let me make clearer what my problem was. I thought as this hashlist has an Integer as key type, either I should get an error if I use something different that an int (which is converted into integer) or another number type is automatically converted into int. This made me wonder.
It is not enough they got same hashCode, when you call get method, the key should also equals the one you put before.
Byte and Integer are different classes, so they are not equal with each other, that's why you got null with table.get(b) or table.get((byte)10).
Related
This question already has answers here:
compareTo Error: Cannot invoke compareTo(int) on the primitive type int
(2 answers)
Closed 2 years ago.
So I am looking to sort an array list of objects based on a field in the object but I am getting an error "Cannot resolve method compareTo(int)"
ArrayList<SuperHero> herolistClone = (ArrayList<SuperHero>) superheroList.clone();
Collections.sort(herolistClone, new Comparator<SuperHero>() {
#Override
public int compare(SuperHero superHero, SuperHero superHeroTwo) {
return superHero.getCiviliansSaved().compareTo(superHeroTwo.getCiviliansSaved());
}
});
}
I assume getCiviliansSaved() returns an int? ints are not objects, thus, cannot be dereferenced (the 'dot' operator cannot be applied to them).
Try Integer.compare(superHero.getCiviliansSaved(), superHeroTwo.getCiviliansSaved());
Or, replace all of it with modern, shiny new java:
heroListClone.sort(Comparator.comparingInt(SuperHero::getCiviliansSaved));
boom, more readable, and turned 5 complicated lines into a single one.
I'm predicting you want to reverse the sort (list the hero that saved the most, at the 0 position in your list), in which case, just slap a .reversed() at the end there, right before the last );.
This question already has answers here:
Hashcode of an int
(4 answers)
Closed 4 years ago.
HashSet hs = new HashSet();
hs.add(1000);
hs.add(new Integer(1000));
System.out.println(hs);
The above code prints [1000] but I have used the new operator which shall create a new object in memory and hence the hash code must be different ,so should it not have two values in hashset?
I have used the new operator which shall create a new object in memory and hence the hash code must be different
That assumption is not correct. The default hashCode implementation returns a different hash for different instances, but that is not a requirement. In many cases you actually want different instances to return the same hashCode (calculated from instance members) to be able to compare instances for equality.
From the documentation of Integer hashCode:
Returns: a hash code value for this object, equal to the primitive int value represented by this Integer object.
If you actually want a map that doesn't use equals/hashCode, take a look at the IdentityHashMap class.
To understand it better lets make a small test, lets find the hashCode of this cases :
int i1 = 1000;
Integer i2 = 1000;
Integer i3 = new Integer(1000);
System.out.println(Integer.valueOf(i1).hashCode());
System.out.println(i2.hashCode());
System.out.println(i3.hashCode());
All the cases return the same hashCode.
Outputs
1000
1000
1000
For that you get one value in the Set and not two like you expected.
Integer's hashcode() method returns hash code value for the object which is equal to the internally stored primitive int value, which in your case is 1000.
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 6 years ago.
I was messing around with lists and got to this code (its a part of the main):
List l1 = new ArrayList<Object>();
List l2 = new ArrayList<String>();
Object t = "a";
l1.add("a");
l2.add(t);
System.out.println(l1.equals(l2));
System.out.println(l2.get(0));
The dynamic type of l2 is ArrayList(type:String) , but I managed to add an Object to it. Moreover, it said the lists are equal. I thought that maybe it casts it to String somehow, but then I tried:
Object t = 9;
And it still worked. Pretty sure it has something to do with the list being a raw type, but still, I can't understand how I can add an object to an ArrayList(type: String). Thanks in advance.
You are declare l2 as raw list. Thus you can add element of any type.
Regarding the equality of the l2 and l1 lists the documentation of equals method on the arraylist class says:
Compares the specified object with this list for equality. Returns
true if and only if the specified object is also a list, both lists
have the same size, and all corresponding pairs of elements in the two
lists are equal
.
The String class is a child of the Object class, so there is an inheritance of objects.
You should not use "equals" with inheritance.
More here : Why should I not use equals with inheritance?
The thing is, the object could be converted back to string, either through an explicit conversion (in this case I'd call it unboxing, like in C#), or by the Java analog of C#'s ToString() method. Either way, the object could successfully be converted to a string so the runtime doesn't complain.
If t was a number converted to an object, either you'd get an exception or you'd get a string representation of that number.
List equality must have been overridden to call the .equals method of the objects in each list.
This question already has answers here:
Why Integer class caching values in the range -128 to 127?
(5 answers)
Closed 6 years ago.
Lets say i have something like
int a = 100;
int b = 100;
Integer c = (Integer) a;
Integer d = (Integer) b;
c == d results to true. Does that mean objects c and d point to the same Object in memory?
Can any one shed light here?
Do we create 2 objects c and d here? Are they different objects or same? == tells me that they are same objects.
I also read somewhere that casting doesn't create new objects. It's just a way of representing the same object. That makes sense if I am trying to cast lets say an Object to a Integer.
But what about this case, where there is no object in picture before (all we had is primitives) and we are trying to create Object c and d here?
Autoboxing works without casting. The reason you're seeing reference equality is because autoboxing internally calls Integer.valueOf() which caches certain values:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
Would (1) int a; new Object[] {a} be the same as (2) new Object[] {new Integer(a)} ?
If I do the 1st one, will (new Object[]{a})[0] give me an Integer?
thank you
Yes and yes.
You can't actually put an int into an Object[]. What you're doing is making use of a feature of Java called autoboxing, wherein a primitive type like int is automatically promoted to its corresponding wrapper class (Integer in this case) or vice versa when necessary.
You can read more about this here.
Edit:
As Jesper points out in the comment below, the answer to your first question is actually not "yes" but "it depends on the value of a". Calling the constructor Integer(int) as you do in (2) will always result in a new Integer object being created and put into the array.
In (1), however, the autoboxing process will not use this constructor; it will essentially call Integer.valueOf(a). This may create a new Integer object, or it may return a pre-existing cached Integer object to save time and/or memory, depending on the value of a. In particular, values between -128 and 127 are cached this way.
In most cases this will not make a significant difference, since Integer objects are immutable. If you are creating a very large number of Integer objects (significantly more than 256 of them) and most of them are between -128 and 127, your example (1) will be probably be faster and use less memory than (2).
What happens under the hood is Java compiler adds code like Integer.valueOf(a) in order to convert your int value into an Object.