Reputation: 753
I can not get this Objects out of a ArrayList I think ArrayList uses the equals method and the hashCode method so I do miss something? This is my Object
public class OPCode {
public String code;
public OPCode(String code){
this.code = code;
}
@Override
public boolean equals(Object o){
OPCode c = (OPCode) o;
return this.code.equals(c.code.substring(0, c.code.length()-2)); // returns ture
}
@Override
public int hashCode() {
return 1;
}
}
and and example
ArrayList<OPCode> t_codes = new ArrayList();
OPCode c = new OPCode("1-202");
t_codes.add(c);
OPCode e = new OPCode("1-202.0");
t_codes.indexOf(e); // -1 <-- Problem here
t_codes.indexOf(c) // finds it
I want e and c to be equal.
Upvotes: -1
Views: 2212
Reputation: 628
Problem is with your equals method.
return (c.code.equals(code)) || c.code.equals(this.code.substring(0, this.code.length() - 2));
Upvotes: 0
Reputation: 1454
Your equals()
and hashCode()
methods are wrong. You are breaking the contract.
If I understood well you want to find the index of e
although there is only c
in the list, and you want to do so abusing the String#equals()
checking equality only for the first 5 letters. So c.code = 1-202
, e.code = 1-202.0
, doing c.code.equals(e.code.subString(0, e.code.lenght()-2))
should hold true
.
This is the correct implementation:
public class OPCode {
public String code;
public OPCode(String code){
this.code = code;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.split("\\.")[0].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;
OPCode other = (OPCode) obj;
if (code == null) {
if (other.code != null)
return false;
} else{
String thisCode = code.split("\\.")[0];
String otherCode = other.code.split("\\.")[0];
if (!thisCode.equals(otherCode))
return false;
}
return true;
}
}
Note that I used the method String#split
since (and this is my assumption) you want to be equal codes with same numerical part without considering decimal part. Using split
we avoid managing variable number of literals.
Test it with:
ArrayList<OPCode> t_codes = new ArrayList<OPCode>();
OPCode c = new OPCode("1-202");
t_codes.add(c);
OPCode e = new OPCode("1-202.0");
System.out.println(t_codes.indexOf(e)); // -1 <-- Problem here now gives 0
System.out.println(t_codes.indexOf(c));
BTW I created both method using eclipse built in function via Source>Generate hashCode() and equals()… and modified for the task.
Upvotes: 2
Reputation: 4165
Your equals()
method is not commutative. I.e. e.equals(c) != c.equals(e)
, so it's not unexpected that you get strange behaviour.
Upvotes: 0
Reputation: 8653
Problem is with your equals method.
t_codes.indexOf(c)
is actually referring to object e
. Because as per your equals method implementation, e is equal to c, but vice versa is not true.
your e.equals(c) != c.equals(e)
. You need to revisit equals implementation.
Upvotes: 0
Reputation: 9179
If you are working with Eclipse. Select the method and press F3 (jdk required). Now you will see implementation:
/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
Upvotes: 0
Reputation: 15333
You have not added the element to the list t_codes.add(e);
t_codes.indexOf(c) // finds it
works because you have added this object to the list t_codes.add(c);
But you have not added your object OPCode e = new OPCode("1-202.0");
to the list. Therefore t_codes.indexOf(e);
gives you -1
Upvotes: 0