Compare a string value with arraylist<object> - java

I have a class of persons.
Public class Person{
private String name = "";
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now I have another class and inside the class I declared an arraylist
public class AddPerson {
public ArrayList<Person> pers = new ArrayList<Person>();
//here we add some persons to the arraylist
pers.add(new Person("Simon"));
pers.add(new Person("Oscar"));
pers.add(new Person("Alfred"));
String name = "Simon";
pers.contains(name); //return false
pers.equals(name); //return false
//I also want to be able to return the value and index of the name in arraylist if it exsists.
if(pers.contains(name)) //return index and value
}
When I try to check if two strings are equal or if a string is already in my list I get both false. I did some research and I saw that I need to override my equals method (and mabey hash and contains method as well). I do not know how to do it and I could not find a good reference how to do it. Please help me to achive that.

Here the problem is you are comparing a Person object with String object using the contains method.So actually in this case there is no point of implementing equals() method and hashCode() methods or using the contains() method to solve this .Only you have to do is check if person's attribute name is equal to your comparing String called name.
Sample solution:
String name="Simon";
Person result = null;//To store the person object if a person name Simon found in the list
int personIndex = -1; //To store the index of founded person
int indexCount =-1;//To maintain the current index value of arrayList
for(Person tempPerson:pers){//Iterating the list to find a person name Simon
indexCount++;
if(pers.getName().equals(name)){
personIndex = indexCount;
result = tempPerson;
}
}
Now you can use the values in personIndex and indexCount variables for future calculations.You can use a condition like if(personIndex >= 0) to check if really a person found with the comparing name after the iteration and then you can get the result variable value.

That is because you are trying to compare a string ("simon") and an object Person built from a string (Person("Simon")). These are two different objects, and it is thus normal to have false as a result.
Whether you want to compare two Person (this would make sense) or you are actually trying to compare a string and a person are it is most certainly a bad idea (you can't actually compare apples and oranges, well this is the same here).
What you might want to do is whether
to override Person's equals method to, for example, return true if they have the same name. => comparing Persons
to iterate on your pers array and fetch it's name property via getName() to compare it with you name string => comparing Strings
1 =>
#Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final Person person = (Person)o;
return name.equals(person.name);
}
#Override
public int hashCode() {
return Objects.hash(name);
}
2 =>
for (final Person person : pers) {
if(name.equals(person.getName())){
// ...
}
}

Related

Find index of an object in a list

I have situation where I have a list(required items) that holds a table column result like:
NAME
ADDRESS
AGE
.
.
etc
In my method I get a User object that contains values for user.getName(), user.getAge() etc. I want to know the best way to ensure that every item in the list is present in the user object. The no of items in the list are variable.
public boolean isUserInfoComplete(User user, ArrayList list){
//so, if the list has AGE, the user.getAge() must have some value
}
One way I thought of is maintaining another list that holds values of every user info and checking that against my db list but that is not scalable.
It's not possible to dynamically match your method names with the list contents without reflection (which can be expensive and fragile). You may want to consider keeping your User values in a central Map cache. Here's one way to do that:
public class User {
private enum Field {
NAME,
AGE
//...
}
private Map<String, Object> values = new HashMap<>();
private void putValue(Field field, Object value) {
values.put(field.name(), value);
}
private Object getValue(Field field) {
return values.get(field.name());
}
public void setName(String name) {
putValue(Field.NAME, name);
}
public String getName() {
return (String)getValue(Field.NAME);
}
public void setAge(int age) {
putValue(Field.AGE, age);
}
public Integer getAge() {
return (Integer)getValue(Field.AGE);
}
//...
public boolean isUserInfoComplete(List<String> fields) {
return values.keySet().containsAll(fields);
}
}
You could use reflection to solve this problem if the items in the list match the getters in your User object.
For example, if AGE is in the list, you could use reflection to look for the getAge() method on the User class, call it on the object, and then check the result for null (or switch on the method return type to perform other types of checks).
Here's a starting point for you to experiment with (I haven't compiled or tested it):
public boolean isUserInfoComplete(User user, ArrayList list){
for(String attribute : list) {
String methodName = "get" + attribute.substring(0, 1).toUpperCase() + attribute.substring(1).toLowerCase();
Method method = User.class.getMethod(methodName, null);
if(method != null) {
Object result = method.invoke(user);
if(result == null) {
return false;
}
}
}
return true;
}
This seems like a case where you need reflection. This gives you the opportunity to inspect methods and field from your objects at runtime.
If you know your User-objects etc will follow a java bean standard then you will be able to use the getters for checking, though I see now problem in making your fields public final and checking directly on the fields themselves.
Take a look at https://docs.oracle.com/javase/tutorial/reflect/
You can check it using contains() while looping. This process will be very resource-consuming.
Maybe you can redesign something and simply compare two User objects? Will be faster. You can do it by providing your own implementation of equals and hashcode methods.

How to update on object at a certain position in an ArrayList?

I have one ArrayList of 10 Objects.
List<Person> persons = new ArrayList<>();
persons.add(new Person("Jean", "Pol", "receptionist", 29));
persons.add(new Person("Jef", "Snijders", "guardener", 42));
persons.add(new Person("Piet", "Peters", "truck driver", 54));
persons.add(new Person("Peet", "Polders", "professor", 63));
persons.add(new Person("Nell", "Van Den Walle", "student", 19));
persons.add(new Person("Nady", "Van Toren", "cleaning", 27));
persons.add(new Person("Jenny", "De Koster", "police", 39));
persons.add(new Person("Malena", "Zetterman", "air traffic controler", 45));
persons.add(new Person("Medina", "Zegers", "test engineer", 25));
persons.add(new Person("Horaire", "Safrina", "manager", 39));
Another method in the applications creates an changed object:
Person changed = new Person("Jean", "Pol", "officer", 30);
How do I find this object in the list, and update the list?
(this should actually update the first object in the list)
This is the Person bean:
public class Person {
private String firstName;
private String lastName;
private String jobTitle;
private int age;
public Person() {
}
public Person(String firstName, String lastName, String jobTitle, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.jobTitle = jobTitle;
this.age = age;
}
// Getters and setters
...
}
Changing an element in the List can be done by :
persons.set(0,changed);
However, finding the index of the element to change requires iterating over the entire List. You should consider using a HashMap instead (where the key identifies the Person).
Then
persons.put (personID, changed);
will replace the Person whose ID is personID (you'll need to have some unique property in the Person class, and override hashCode and equals in order to make that work).
You should tell java about "On what basis should i consider two person equals"? For that you have to override equals() method and do an equality check based on firstName and lastName. However since it is a list, so you will have to iterate over it and use contains(Person p) method to check if it exists (Which will use equals method). Once you find a matching Person object, you can replace it (using the index).
first decide which property or properties can be used to verify if 2 objects are equal then override equals and hashcode for persons and then iterate and compare then replace when found.
the best approach to find the object is to override two methods equals(Object o) and hashCode() within your Person class, this will define a unique Person
your Person class:
class Person {
...
#Override
public boolean equals(Object o){
// your code here
}
#Override
public int hashCode(){
//your code here
}
}
if ordering is not important to you , you can use HashMap
for example :
Person p;//
myMap.put(p.hashCode(),p);
then from other part of your application you get your person;
Person otherP;//
myMap.put(otherP.hashCode(), otherP) // this will replaces the previous person with the same hashCode with the modified code
if you don't want to add a person that is not already there, you can check if it exists first
if(myMap.containsKey(otherP.hashCode()){
myMap.put(otherP.hashCode(), otherP);//
}
generate hashcode and equals methods in your bean class for the variable you want to check for similarity (in your case the firstName property in person class).if using eclipse then pressing ctrl+shift+s shows you the option to generate hashcode and equals methods.
what this does is to override the default equals method. Please make sure that you are selecting only the properties which you know will be same.
if (List.contains(new_object)) { // checking if object is in the list
int indexPos = List.indexOf(new_object); // getting the index if there
dbStockObjList.set(indexPos, new_object);//adding it in the index
}
the hashcode and equals methods for your bean would look like this:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((firstName == null) ? 0 : firstName.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;
Person other = (Person) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
return true;
}
hope this answers your question properly.
You can use the List#indexOf(obj) method to get the index of the "identical" object, and update it using List#set(index, object).
Note that it will require you to override equals() method for your object.
Also note: this operation is inefficient, and if the list is large and the number of changes is frequent - consider switching from a list to a "smarter" data type, such as a Set.

How to create a set of deep objects

I have a collection of objects, A.
class A{
String name;
Collection<B> listOfB;
}
class B {
String address;
String phone;
int age;
}
I want to create new collection of A objects, where 2 objects have the same name, address, and phone. Can anyone tell me if this is the best way to do this?
I create a map of Key-A. The key would be as follows:
Key {
String name;
String address;
String phone;
}
I only as A objects to the list if their corresponding Key is not present.
If I understand your question correctly you want a map Map<Key, A>. The important thing is that you define equality and the hash code (in case you want a hash map) for the Key:
class Key {
String name;
String address;
String phone;
#Override // override in Object
public boolean equals(Object other) {
if(!other instanceof Key) return false;
Key otherKey = (Key) other;
return name.equals(otherKey.name) && address.equals(otherKey.address) && phone.equals(otherKey.phone); // check for null if fields can be null
}
#Override // override in Object
public int hashCode() {
return name.hashCode() ^ address.hashCode() ^ phone.hashCode(); // or something along those lines
}
}
Also good idea to create a constructor for the Key and make the fields private and final.
I'm not sure how this key is derived though. Ideally, the Key would somehow be derived from A, or - even better - A would have a hashCode and equals method so you do not need a map but you can use a Set. This really depends on the data you want to model though and your question is not clear enough to give a specific recommendation.
First, implement hascode and equals method in class B.
In equals method return true when name,phone and adress are the same.
Second time, create your map like this=
HashMap<B,A> myMap;
A key in a map is always unique.

What is use of hashCode() and equals() method in Java?

I have little problem with java. i am not able to get accurate result.
what's wrong with this code please help me out from this code
your own objects as keys in Maps or in Sets. To use your own objects as keys in Maps or in Sets.code not executing correctly..
what is use of hashcode and equals in java.
Code:
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
class Person {
private int id;
private String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "{ID is: " + id + "; name is: " + name + "}";
}
}
public class App {
public static void main(String[] args) {
//creating person object
Person p1 = new Person(0, "Bob");
Person p2 = new Person(1, "Sue");
Person p3 = new Person(2, "Mike");
Person p4 = new Person(1, "Sue");
Map<Person, Integer> map = new LinkedHashMap<Person, Integer>();
//putting on map
map.put(p1, 1);
map.put(p2, 2);
map.put(p3, 3);
map.put(p4, 1);
//displaying the result
for(Person key: map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
//using set
Set<Person> set = new LinkedHashSet<Person>();
//adding on set
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
//displaying the result
System.out.println(set);
}
}
Expected Output:
{ID is: 0; name is: Bob}: 1
{ID is: 1; name is: Sue}: 1
{ID is: 2; name is: Mike}: 3
[{ID is: 0; name is: Bob}, {ID is: 1; name is: Sue}, {ID is: 2; name is: Mike}]
The equals() and hashCode() methods are both implemented in the superclass Object.
In real worl applications, you may incounter the need to override both of these methods but don't do unless you understand their utility. I'll try to give the best in short:
equals() method is used for equivalence relations.
hashCode() is used to provide, as it reveals, a hash code which is a 32-byte representation of the object.
Imagine that you have a class Person with below declaration:
public class Person {
public int nationalIdentityNumber;
public String firstName;
public String secondName;
public Person (int nationalIdentityNumber, String firstName, String secondName) {
this.nationalIdentityNumber = nationalIdentityNumber;
this.firstName = firstName;
this.secondName = secondName;
}
}
When not overriding the equals() methods:
Person p1 = new Person(1234,"Jhon","Legend");
Person p1 = new Person(1234,"Mary","Richard");
When we call p1.equals(p2) this will result in a false result thus the default method from Object class compares the objects references. But what I actually you may need is that two Persons are considered equals when their nationalIdentityNumber instance variable is equal so you need to override the equals() implementation as below:
#Override
public boolean equals(Object object) {
boolean result = false;
if (object == null || object.getClass() != getClass()) {
result = false;
} else {
Person person = (Person) object;
if (this.nationalIdentityNumber == person.nationalIdentityNumber) {
result = true;
}
}
return result;
}
So p1.equals(p2) will now return a true result.
Now back to hashCode, imagine you are registering your Person objects in a HashSet
HashSet<Person> personsHS = new HashSet<Person>();
personsHS.add(p1);
personsHS.add(p2);
When invoquing
System.out.println("personsHS.contains( new Person(1234,Jhon,Legend))--->>>"+personsHS.contains(new Person(1234,"Jhon","Legend")));
it will result in personsHS.contains( new Person(1234,"Jhon","Legend"))--->>>false statement because the HashSet is using the default Object#hashCode() method to determine the equality of keys thus we need to override it to ensure the Person uniqueness (based on your requirements) inside the hashtables:
#Override
public int hashCode() {
return this.nationalIdentityNumber;
}
So that
System.out.println("personsHS.contains(new Person(1234,Jhon,Legend))--->>>"+personsHS.contains(new Person(1234,"Jhon","Legend")));
will result in personsHS.contains( new Person(1234,"Jhon","Legend"))--->>>true
This is a simplest that it could be but note that it will always depend on your application and your own objects to wether or not to override this methods and which fashion to do so.
BR.
Cfr the general contract for hashCode:
If two objects are equal according to the equals(Object) method, then
calling the hashCode method on each of the two objects must produce
the same integer result.
In java, to use your own objects in some fonctionnalities you sometimes need to create some "generic" fonctions. HashCode and Equals for instance.
To use your objects in a hashmap like you are doing, java needs those. So you have to implement them in your "person" class. Here is an article explaining why in some case we need to override these methods and what exactly they are doing:
http://javarevisited.blogspot.ca/2011/02/how-to-write-equals-method-in-java.html
Normally you can auto-generate them withing your IDE, in NetBeans you can go to: Source - Insert Code - Equals and Hashcode.
Then it should work.

removig items from arraylist

In an ArrayList, I have the same kind of objects. Each object has an id, name, and number as their fields. There is a chance that more than one object will have the same phone number. How can I make the ArrayList in such a way that all the ArrayList objects have distinct phone numbers?
override in your class methods equals() and hashCode(). In equals you will compare by phone number. Generate hashcode from your phone number too.
Now you are ready to use Set interface which will compare your objects by phone numbers automatically and exclude duplicates.
example below:
public class Test {
private int id;
private String name;
private String phoneNumber;
public Test(int id, String name, String phoneNumber) {
this.id = id;
this.name = name;
this.phoneNumber = phoneNumber;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test test = (Test) o;
return phoneNumber.equals(test.phoneNumber);
}
#Override
public int hashCode() {
return phoneNumber.hashCode();
}
}
now instead of using List<Test> arr = ArrayList<Test>(), use Set<Test> mySet = new HashSet<Test>().
Try Set.
A collection that contains no duplicate elements.
First solution that comes to my mind is to use a HashMap.
Simply create a HashMap with the 'phonenumber' as key and your object as the value. After adding all the elements, you will have the list of objects with unique phone numbers. Simply iterate over this to create the List that you need.

Categories

Resources