I know that the below code gives the index of that particular element in java.
List<String> list = new ArrayList<>();
list .add("100");
Log.d("TAG",String.valueOf(list.indexOf("300")));
But how to get the index of an element while using a helper Class?
List<HelperClass> Arraylist= new ArrayList<>();
Arraylist.add(new HelperClass(name, email, phoneno));
Log.d("TAG", String.valueOf(new HelperClass(Arraylist.indexOf(name,email,phoneno))));
I searched everywhere for this but couldn't find. Can someone tell me how to find index of a particular item in arraylist while using modal to add data?
Obviously what I have tried is wrong and it shows red line under the whole line but I just typed that code for your understanding of what I want to achieve. Can someone give me a way please?
Helper
#Override
public int hashCode() {
int result = getName() != null ? getName().hashCode() : 0;
result = 31 * result + (Email != null ? Emaail.hashCode() : 0);
result = 31 * result + (PhoneNo!= null ? PhoneNo.hashCode() : 0);
return result;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Helper)) return false;
Helperthat = (Helper) o;
if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null)
return false;
if (Email != null ? !Email.equals(that.Email) : that.Email != null)
return false;
if (PhoneNo != null ? !PhoneNo.equals(that.PhoneNo) : that.PhoneNo != null)
return false;
}
ArrayList#indexOf uses the Object#equals comparison method.
If you want to be able to lookup a HelperClass instance inside a Collection, you need to provide your own, overridden, equals method, and possibly also the hashCode one, for use with other, specific, Collection implementations (Map, Set, etc.).
class HelperClass {
...
#Override
public boolean equals(final Object object) {
if (object == this) {
return true;
}
if (!(object instance of HelperClass)) {
return false;
}
final HelperClass other = (HelperClass) object;
return name.equals(other.name) &&
email.equals(other.email) &&
phone.equals(other.phone);
}
}
You obviously need to have an appropriate HelperClass instance to find a match.
final String name = "Name";
final String email = "Email";
final String phone = "Phone";
final HelperClass first = new HelperClass(name, email, phone);
final HelperClass second = new HelperClass(name, email, phone);
final List<HelperClass> helpers = new ArrayList<>(8);
helpers.add(first);
final int index = helpers.indexOf(second); // index = 0
indexOf requires the object as input. If it does not find the object you are passing in, it will return -1. You need to pass the object whose location in the arraylist you are looking for as the input into the indexOf function.
Solution :
create a HelperClass to pass into the indexOf method:
.indexOf(new HelperClass(name, email, phoneno));
However that change by itself will still return -1. See the api doc for indexOf:
public int indexOf(Object o)
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 i such that (o==null ? get(i)==null
: o.equals(get(i))), or -1 if there is no such index.
It's using equals to decide whether it's found a match. You should have overridden the equals method on your HelperClass class, so it's using the default implementation in java.lang.Object, which compares the references, and only returns true if the two references HelperClass to the same object.
Override equals and hashcode on your HelperClass class, like:
#Override public boolean equals(Object other) {
if (!(other instanceof HelperClass)) {
return false;
}
HelperClass otherHelperClass = (HelperClass)other;
return otherHelperClass.x == this.x && otherHelperClass.y == this.y;
}
#Override public int hashCode() {
return x + y; // same values should hash to the same number
}
Related
i'm new in java collections so i tried to codes using Map.
i set my collection like this
Map<Integer, Person> people = new HashMap<>();
people.put(1, new Person("Arnold", "Maluya", 25));
people.put(2, new Person("Mison", "Drey", 3));
people.put(3, new Person("James", "Valura", 54));
people.put(4, new Person("Mikee", "Sandre", 24));
so my goal is i want to check if people contains object like "new Person("Arnold", "Maluya", 25)" so what i did is this
boolean test = people.containsValue(new Person("Arnold", "Maluya", 25));
System.out.println(test);
which is i getting "false" result. so am i getting it right so if sumthing is wrong what did i miss?
Implement an equals, example:
public class Person {
private String name;
private String lastName;
private String age;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (name != null ? !name.equals(person.name) : person.name != null) return false;
if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) return false;
return age != null ? age.equals(person.age) : person.age == null;
}
#Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
result = 31 * result + (age != null ? age.hashCode() : 0);
return result;
}
}
The methods hashCode() and equals() play a distinct role in the objects you insert into Java collections.
equals() is used in most collections to determine if a collection contains a given element.
When inserting an object into a hastable you use a key. The hash code of this key is calculated, and used to determine where to store the object internally. When you need to lookup an object in a hashtable you also use a key. The hash code of this key is calculated and used to determine where to search for the object.
When you use your custom java objects in collections, its always advisable to override hashCode() & equals() methods, to avoid weird behaviors.
The behavior is correct as you are not overriding the equals method in Person class. Map will consult with equals method of the object stored in it to identify whether the query is matching with stored values. You must override the equals method in your object and implement logic appropriately to determine whether object passed as an argument is matching or not.
Note: Below code doesn't check for null values and hence may throw an exception. You need to put additional conditions to avoid null pointer exceptions.
#Override
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person other = (Person) obj;
if ((other.firstName.equals(this.firstName)) && (other.lastName.equals(this.lastName))
&& (other.age == this.age)) {
return true;
}
return false;
}
I have a Map in Java like so,
private HashMap<String, Object[][]> theMap;
Where the key is a String and the entry is going to be something along the line of,
theMap = new HashMap<>();
Object[][] theData = {
{Boolean.FALSE, "Text"}
};
theMap.put("Key1", theData);
Somewhere along the line I would like to check if an entry in the map is equivalent to another object. Currently I am doing it like this,
Object[][] tempData = {
{Boolean.FALSE, "Text"}
};
for(Object key: entries.keySet()) {
if(entries.get(key).equals(tempData)) {
entries.remove(key);
}
}
And it is not working.
I would prefer the comparison to be done with an object rather than with another map. I'm wondering what I'm doing wrong with this comparison here?
The reason you are not getting equality is that arrays inherit Object#equals() which is based on identity, not equality of contents. You could consider using java.util.Arrays.deepEquals(Object[], Object[]) to compare.
That is the answer to the immediate question. However, using a 2-dimensional array of Object to hold a boolean and a String is really bad code smell and indicates you need to encapsulate what you are putting in the array.
Identity vs Equivalence
Please make sure that you understand that by default the equals() method of Object checks on whether two object references are referring to the same object (identity), which is not what your code is checking.
Instead, your code is checking whether the two objects (the values you put on the map) are having the same value (equivalence).
Here are two articles about this topic:
What is the difference between identity and equality in OOP?
Overriding equals method in Java
In this particular problem of yours, I think the solution involves two steps:
Your tempData and theData does not seems to be an array
of elements of the same type (it does not appear to be a 2-dimensional
array either). Instead, it contains a Boolean value and then a
String value. In this case, I think you really should think
through what this thingy is and design a class for it (I am showing
an example below)
The class should override the equals() (and hashCode()) methods
so that you can use its equals() for equivalence checking.
Note also that your IDE (e.g. Eclipse) probably can generate a template for equals() and hashCode() for you.
Example: (here I assume your Boolean represents a condition, and your String represents a message)
class MyRecord {
private Boolean condition;
private String message;
public Boolean getCondition() {
return condition;
}
public void setCondition(Boolean condition) {
this.condition = condition;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((condition == null) ? 0 : condition.hashCode());
result = prime * result
+ ((message == null) ? 0 : message.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;
MyRecord other = (MyRecord) obj;
if (condition == null) {
if (other.condition != null)
return false;
} else if (!condition.equals(other.condition))
return false;
if (message == null) {
if (other.message != null)
return false;
} else if (!message.equals(other.message))
return false;
return true;
}
}
Say I have an object which has an id: String and name: String field.
If I have an array of these objects, if I use the remove method, since technically the Object pointer is different, the object I want won't get removed.
Ex:
List<ObjectA> newList = new ArrayList<>();
// Objecta1(id: a, name: a)
// Objecta2(id: b, name: b)
// Objecta3(id: b, name: b)
newList.add(objecta1);
newList.add(objecta2);
newList.remove(objecta3); --> will equal false
What is the cleanest way to have remove do this correctly?
I searched around and found that I could use removeIf and do a comparison there. I also could use an Iterator and then compare the fields myself. Just wondering if there is a canonical, clean way of doing it in Java. Thanks.
Beside the solution override equals, you can do it with java 8:
newList.removeIf(p -> p.getId().equals(objecta3.getId()));
Your object should #Override the equals method.
Add the following to your class:
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ObjectA)) return false;
ObjectA objectA = (ObjectA) o;
if (getId() != objectA.getId()) return false;
return getName() != null ? getName().equals(objectA.getName()) : objectA.getName() == null;
}
#Override
public int hashCode() {
int result = getId();
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
return result;
}
and then:
while(newList.remove(objecta3)){};
I have a Class Levels which has a hashMap declared.
public class Levels{
private final Map<Unit, Object1> rateUnitCost;
public Levels(Map<Unit, Object1> levels) {
this.rateUnitCost = new HashMap<Unit, Object1>(levels);
}
public Object1 getCoverageLevel(Unit unit, Phase aP) {
return rateUnitCost.get(unit);
}
}
I am calling getCoverageLevel() method from other class and i am instantiating the Levels class rateUnitCost property as well from another class.
When seeing in debugger i am finding this value for rateUnitCost and unit object.
rateUnitCost: - Hash Map Values
rateUnitCost HashMap<K,V> (id=1248)
[0] HashMap$Node<K,V> (id=1266)
key >Unit (id=1249)
amount Money (id=1267)
flags ArrayList<E> (id=1268)
procedureId 7156
ParticipationId 104152413
value >Object1 (id=1250)
Now value of unit object is below :-
unit Unit (id=1251)
amount Money (id=1258)
flags ArrayList<E> (id=1259)
procedureId 7156
ParticipationId 104152413
when i match the value of key with this object then its matching .
But at the time of rateUnitCost.get(unit) its returning null even though Object1 is set. Object1 is getting returned from other class using below line: -
return new Object1();
Can anyone please help me to resolve this mystery.?
BasicUnit is a class which is implementing the Unit interface. BasicUnit have equals method as below :-
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BasicUnit basicUnit = (BasicUnit) o;
if (flags != basicUnit.flags) return false;
if (procedureId != basicUnit.procedureId) return false;
if (ParticipationId != basicUnit.ParticipationId) return false;
if (amount != null ? !amount.equals(basicUnit.amount) : basicUnit.amount != null) return false;
return true;
}
and HashCode :-
public int hashCode() {
int result = procedureId;
result = 31 * result + ParticipationId;
result = 31 * result + (amount != null ? amount.hashCode() : 0);
result = 31 * result + (flags == null ? null : flags.hashCode());
return result;
}
if (flags != basicUnit.flags) return false;
You are checking for whether your Unit objects have exactly the same ArrayList of flags. This is not an equals()-type equality check; this is checking for literally the same ArrayList of flags. Now, you haven't provided the constructor etc, but I highly doubt you are reusing the same ArrayList.
Check for !(flags.equals(basicUnit.flags)) instead. Do note that ArrayList.equals() uses the E.equals() implementation, so be sure that that is implemented.
Also, note that ArrayList.equals() checks for the same list entries in the same order. I don't know if the order of your flags matters but I suspect it probably does not. You might consider making your flag collection a Set if this is the case.
I have a class for a string-number pair. This class has the method compareTo implemented.
A method of another class returns a collection of elements of the pair type.
I wanted to perform a unit test on this method, and therefore wrote the following:
#Test
public void testWeight() {
Collection<StringNumber<BigDecimal>> expected = new Vector<StringNumber<BigDecimal>>();
expected.add(new StringNumber<BigDecimal>("a", BigDecimal.ONE));
expected.add(new StringNumber<BigDecimal>("b", BigDecimal.ONE));
Collection<StringNumber<BigDecimal>> actual = new Vector<StringNumber<BigDecimal>>();
expected.add(new StringNumber<BigDecimal>("a", BigDecimal.ONE));
expected.add(new StringNumber<BigDecimal>("b", BigDecimal.ONE));
//Collection<StringNumber<BigDecimal>> actual = A.f();
assertEquals(expected, actual);
}
But as you can see, the assertion fails, even though the elements in the collections are identical. What can be the reason?
The error I get is
java.lang.AssertionError: expected: java.util.Vector<[a:1, b:1]>
but was: java.util.Vector<[a:1, b:1]>
Which does not make scene to me.
Your StringNumber class requires equals() method. Then it will work. Assuming this class contains string and number fields (auto-generated by my IDE):
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof StringNumber)) {
return false;
}
StringNumber that = (StringNumber) o;
if (number != null ? !number.equals(that.number) : that.number != null) {
return false;
}
return !(string != null ? !string.equals(that.string) : that.string != null);
}
#Override
public int hashCode() {
int result = string != null ? string.hashCode() : 0;
result = 31 * result + (number != null ? number.hashCode() : 0);
return result;
}
Few remarks:
Two Vector's (why are you using such archaic data structure) are equal if:
both [...] have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elements e1 and e2 are equal if (e1==null ? e2==null : e1.equals(e2)).)
That's why overriding equals() is required.
when implementing equals() you must implement hashCode(). Not required here, but better be safe than sorry: What issues should be considered when overriding equals and hashCode in Java?.