hashCode(): return of an integer after string - java

I don't understand in this code the hashcode() methode: how can you return an integer if there is a string... Basically you add a string next to a number but that doesn't maje it a string
also i don't understand the function equals, what is a object o and what is a o insteadof
public Imatriculation(int numeros, String word) {
this.numeros = numeros;
this.word = word;
}
public int hashCode() {
return this.word.hashCode() + this.numeros;
}
public boolean equals(Object o) {
return o instanceof Imatriculation
&& this.word.equals(((Imatriculation) o).word)
&& this.numeros == ((Imatriculation) o).numeros;
}

As was already pointed out hashcode returns an int not a string.
"o" is simply any object in java, it could be anything, so instanceof is used to check if object "o" is an Imatriculation before going on and checking the details of the object.

String#hashCode() is overriden from Object#hashCode() thus it also returns int. From the String source:
public int hashCode() { // <- it returns int!!!
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
The main purpose of hashCode() is "numerically represent" instance of a class in order to determine, which bucket of hash table it should occupy.

Related

Using a customed class as keys to in HashMap but not able to search the keys

I created a HashMap that uses a customed class Location as keys.
After inserting all the entries into the HashMap using put(), I am not able to search the keys.
I have tried to use get() or containsKey() to search, but neither give me positive results. However, I am sure that the keys do exists in the code because I have used HashMap iteration to print out the keys.
Below is the code:
public HashMap<Location, Integer>beenTo = new HashMap<>();
public int uniquePathsIII(int[][] grid) {
for (int i=0; i<grid.length; i++){
for (int j=0; j<grid[0].length; j++){
if (grid[i][j] == 0 || grid[i][j] == 2){
Location newSquare = new Location(i,j);
notBeen.put(newSquare, 1);
}
}
}
Location newSquare = new Location(0,1);
if (notBeen.get(newSquare) != null){
return 10;
}
if (notBeen.isEmpty()){
return -1;
}
}
Below is the class Location:
class Location{
int i; // row
int j; // column
public Location(int _i, int _j){
i = _i;
j = _j;
}
public int getI(){
return i;
}
public int getJ(){
return j;
}
public void setI(int _i){
i = _i;
}
public void setJ(int _j){
j = _j;
}
}
In the above code, I wanted to search for the key Location(0,1). I have made sure that the Hashmap notBeen is not empty, and tried that the key does exist. But I am never able to find it using containsKey() nor get().
You need to implement/override hashCode and equals methods if you want a custom Object to work as a key in a HashMap in Java.
FYI:
_variableName goes against Java naming conventions Oracle Java Naming Convention. It is also not necessary as you can get the same result using:
public Location(int i, int j){
this.i = i;
this.j = j;
}
In order to avoid memory leaks map's key must be immutable object,and improve search key speed,the key object has equals() and hashcode() methods is good practice(first use hashcode judge equals then use equals() method).In your code it is best to make location immutable(not support setter methods).
public class Location {
private final int i;
private final int j;
public Location(int x, int y) {
this.i = x;
this.j = y;
}
public int getI() {
return i;
}
public int getJ() {
return j;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Location)) {
return false;
}
Location point = (Location) o;
return i == point.i &&
j == point.j;
}
#Override
public int hashCode() {
return Objects.hash(i, j);
}
}

Correctly implement hashcode for matrix java

I have a Java class containing a 2D int array. I want to implement the hashCode() method so that different objects can be compared using their attributes and not reference. This is what I tried:
public int hashCode() {
int hash = 0;
for(int i=0; i<getMatrix().length; i++) {
hash =+ Arrays.hashCode(getMatrix()[i]);
}
return hash;
}
I also tried using deepHashCode() but didn't work. My problem is that when the get() method of a HashMap object is used, even though both the object have the same matrix, the get() method does not work properly.
EDIT:
Implementation of equals method
public boolean equals(Object o) {
boolean sameBoard = false;
if(o != null && o instanceof Node) {
Node node = (Node) o;
int[][] board1 = this.getMatrix();
int[][] board2 = node.getMatrix();
return Arrays.deepEquals(board1, board2);
}
return sameBoard;
}

Java HashSet contains function not working

I am writing a simple program as follow: Given two numbers M and N, p is from [M,N] and q is from [1,p-1], find all irreducible fractions of p/q.
My idea is brute force all possible value of p, q. And using HashSet to avoid duplicated fraction. However, somehow the contains function not working as expected.
My code
import java.util.HashSet;
import java.util.Set;
public class Fraction {
private int p;
private int q;
Fraction(int p, int q) {
this.p = p;
this.q = q;
}
public static int getGCD(int a, int b) {
if (b == 0)
return a;
else
return getGCD(b, a % b);
}
public static Fraction reduce(Fraction f) {
int c = getGCD(f.p, f.q);
return new Fraction(f.p / c, f.q / c);
}
public static HashSet<Fraction> getAll(int m, int n) {
HashSet<Fraction> res = new HashSet<Fraction>();
for (int p = m; p <= n; p++)
for (int q = 1; q < p; q++) {
Fraction f = new Fraction(p,q);
Fraction fr = reduce(f);
if (!res.contains(fr))
res.add(fr);
}
return res;
}
public static void print(Fraction f) {
System.out.println(f.p + "/" + f.q);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<Fraction> res = getAll(2, 4);
for (Fraction f : res)
print(f);
}
}
Here is the output of program
4/3
3/1
4/1
2/1
3/2
2/1
you can see the fraction 2/1 is duplicated. Anyone can help me figure out why and how to fix it.
Many thanks.
Override the Object#equals and Object#hashCode methods in the Fraction class. These methods are used by HashSet to determine if two objects are the same. When you don't override them, the equals method tests equality of the objects' references rather that equality of their field values.
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + p;
result = prime * result + q;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Fraction other = (Fraction) obj;
if (p != other.p)
return false;
if (q != other.q)
return false;
return true;
}
You need to implement Fraction#equals() and Fraction#hashcode(), because that is used for determining weather the set contains certain value or not. Without it, object references are compared, which will not give you the desired result.
Your Fraction class does not override hashCode and equals. A HashMap contains tries to find a key with the same hashCode (and equals) as the one you provided. As you create a new instance of Fraction, it will never be the same as the one already in the HashMap. Here is how you would do hashCode and equals:
#Override
public int hashCode() {
return super.hashCode() + p * 24 + q * 24;
}
#Override
public boolean equals(Object other) {
if (!(other instanceof Fraction)) return false;
return ((Fraction) other).p == this.p && ((Fraction) other).q == this.q;
}

Implementation of hashCode and equals in int[] Java

It looks like the hashCode() and equals() for int[] are poorly implemented, or not implemented at all!
(Tested with Android, but I expect it to be true for any Java environment).
In order to get HashSet.contains() working properly, I had to create a wrapper for int[] (plse, don't criticize my coding style, look at the essence):
public class IntArray {
private int[] value;
public IntArray(int[] value) {
this.value = value;
}
#Override
public int hashCode() {
int sum = 0;
// Integer overflows are cheerfully welcome.
for (int elem: value) sum += elem;
return sum;
}
#Override
public boolean equals(Object o) {
if (o == null) return (value==null);
if (value != null) {
if (o instanceof int[])
return compare((int[])o);
if (o instanceof IntArray)
return compare(((IntArray)o).value);
}
return false;
}
protected boolean compare(int[] other) {
int len = value.length;
if (other.length != len) return false;
for (int i=0; i<len ; i++)
if (value[i] != other[i]) return false;
return true;
}
}
Works OK, but I prefer to avoid a custom wrapper or a third-party library. Is there an option?
Since the standard Java Hashtable does not allow an override of the hash code used for keys, you are out of luck and will need to use a wrapper like you did.
keep in mind that your hashCode implementation is very bad, you can use this (Taken from java.util.Arrays in the standard JDK) to get a better hash distrubtion:
public static int hashCode(int a[]) {
if (a == null)
return 0;
int result = 1;
for (int element : a)
result = 31 * result + element;
return result;
}
An alternative is to use a different Hashtable, which can deal with primitives.
one such option is Banana, which is a primitive collections library I created.
After Omry Yadan's message the hashCode function becomes as simple as that!
#Override
public int hashCode() {
return Arrays.hashCode(value);
}
For a RISC CPU, like ARM, It may be more efficient:
#Override
public int hashCode() {
int code = 0;
if (value != null) {
code++;
for (int elem: value)
code = (code<<5) - code + elem;
}
return code;
}
May be there is also a standard function for comparing arrays, in which case equals() can be simplified too?

how does default equals implementation in java works for String? [duplicate]

This question already has answers here:
Demonstrating string comparison with Java
(3 answers)
Closed 9 years ago.
We all know if we create two String objects and use == to compare them it will return false and if we use equals to method it will return true. But by default equals method implement == only , then how does it return true , it should return whatever == is returning ??
Yes by default equals method implements == in Object class . But you can Override the equals method in your own class to change the way equality is done between two objects of the same class. For example the equals method in String class is overridden as follows:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
So this is the reason that for the following code:
String s1 = new String("java");
String s2 = new String("java");
s1==s2 returns false since both are referencing different objects on heap. Whereas s1.equals(s2) returns true since now the equals being called is what defined within String class where String objects are compared on the basis of contents of String.
the equals method in the String class is overridden and it tries to check if all the characters in both the Strings are equal or not. If found then it returns true. So the behavior of equals method in String class is different from the normal object class implementation of it.
.equals() checks if the strings are identical ei. have the same characters. == only checks if pointers point to the same objects. You can have different objects with the same characters, thats why you should use .equals() to compare them
String class in java overrides the equals method of Object class such that it compares the content of the two strings rather than comparing the references(default implementation of in Object class).
See below the equals method implementation of String class:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
equals method is originally a method of Object class. And every class in Java extends the Object class by default. Now, equals method is overridden for String class to act differently than ==.
It's javadoc explains it perfectly:
Compares this string to the specified object. The result is
true if and only if the argument is not null and is a
String object that represents the same sequence of characters as this
object.
It's implementation goes as follows:
#override
public boolean equals(Object anObject) {
// This check is just for the case when exact same String object is passed
if (this == anObject) {
return true;
}
// After this only real implementation of equals start which you might be looking for
// For other cases checks start from here
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}

Categories