Reputation: 457
I am trying to find a specific object based on user input. The user is to enter a name and a gender and then the program is supposed to search an ArrayList and see if there is a name and gender that matches. The object in the ArrayList has 3 instance variables, but the program only searches for 2. How can I search for only a select few characteristics in an ArrayList?
In my program I have:
int nameListLength = nameList.size();
.
.
.
boolean done = false;
while (!done) {
System.out.println ("Please enter a name:");
String searchName = input.nextLine();
if (searchName.equals("DONE")) {
done = true;
} else {
System.out.println ("Please enter a gender:");
String searchGender = input.nextLine();
// Search the ArrayList.
for (int i = 0; i < nameListLength; i++) {
// See if the gender is in the ArrayList
if (searchGender.equals(nameList.get(i).getGender())) {
// See if the name matches the gender in the ArrayList
if (searchName.equals(nameList.get(i).getName())) {
System.out.println ("Match found");
}
}
}
}
}
Where nameList is the name of the ArrayList, getName() is the name of the method that returns the name stored in the object, and getGender() is the name of the method that returns the gender stored in the object. I put in debug statements to determine that the ArrayList is stoing the information correctly, I'm just having problems figuring out how to search for what I am looking for. I know there is a contains(Object o) method, but I am not sure if I can implement that here since I only need to match 2 characteristics of the object even though the object contains 3 pieces of data.
Upvotes: 0
Views: 9570
Reputation: 635
in your "Person" object @Override the equals method, then use contains() method from collection.
`@Override
public boolean equals(Object obj) {
final Product other = (Product) obj;
if (obj==null){
return false;}
else if(this.name.equals(other.name) && this.gender.equals(other.gender{
return true;}
else{
return false;}
}`
Upvotes: 0
Reputation: 8552
Generally your code looks ok even if it is a bit untidy. You claim that it does not work, but I cannot see the obvious bug so I would double check the input list and the search terms (like case specificity for example).
Do not override the equal just to be able to use contains as it would imply that you always are going to compare your object just by those two properties.
You may consisder using the new Stream API which has few methods that does exactly what you are looking for:
List<Yourtype> found = list.stream().filter(u -> u.getName().equals(searchName) && u.getGender().equals(searchGender)).collect(Collectors.toList());
check if there is a matching element
boolean isMath = list.stream().anyMatch(u -> u.getName().equals(searchName) && u.getGender().equals(searchGender));
take first matching:
Yourtype match = list.stream().findFirst(u -> u.getName().equals(searchName) && u.getGender().equals(searchGender)).get();
Upvotes: 2
Reputation: 15729
Collection.contains()
ultimately uses equals()
and hashCode()
of your Object (Name? - I'm calling it that in this post). It would work if you wrote Name.equals() and Name.hashCode() to only use the two fields, not all three. However, that is probably incorrect. At some other time the third field would be important. Unfortunately, in Java, you cannot "plug and play" different equals() methods. At least, not at all easily.
However, you can use a Comparator along with the utilities in Collections. For example, within your Name class, implement
public static final NAME_AND_GENDER_COMPARATOR = new Comparator<Name>() {
// code goes here
}
Then, call (you might want to do this on a copy of nameList, as it will reorder it)
Collections.sort(nameList, Name.NAME_AND_GENDER_COMPARATOR);
Now, everything is sorted. Then call
Name searchFor = new Name(theName, theGender); // make a mock Name to search for
int index = Collections.binarySearch(nameList, searchFor, Name.NAME_AND_GENDER_COMPARATOR);
if (index >= 0)
// found it
Upvotes: 0
Reputation: 427
As far as I understood your question, you want to fetch the matching Object based on the input.
You already posted a viable solution. You only need to get the Object with nameList.get(i) where your System.out.println ("Match found") is.
You can also use for()-Loops to cycle through every item in the list, so you don't need to take the long way by using the lenght.
boolean done = false;
YourObject result;
while (!done) {
System.out.println ("Please enter a name:");
String searchName = input.nextLine();
if (searchName.equals("DONE")) {
done = true;
} else {
System.out.println ("Please enter a gender:");
String searchGender = input.nextLine();
// Search the ArrayList.
for (YourObject item: nameList) {
// See if the gender is in the ArrayList
if (searchGender.equals(item.getGender())) {
// See if the name matches the gender in the ArrayList
if (searchName.equals(item.getName())) {
result = item;
}
}
}
}
}
result would be your matching Object
Upvotes: 0
Reputation: 1150
To use the List.contains method,you will need to implement the equals() method on the object that contains the data, so it can determine if the object is truly equal to another object.
In your instance you will simply implement that 2 out of 3 pieces of data needs to be equal so then the equals() method can return true.
Upvotes: 0