'How do I know if an array list of objects contain a certain string?

I made a method that search through an array list of objects. Then if the searchKey is found in the array list it will print this certain item.

Here is how I iterate through the array list if it contains the searchKey, but I just realized that it is impossible to compare a string and an object.

for(int x = 0; x < Student.students.size(); x ++){
    if(Student.students.contains(searchKey))
        System.out.print(Student.students.get(x));
}

Here's how I create the constructor and array list.

String firstName, lastName, course, yearLevel, gender;
    
    Student(String firstName, String lastName, String course, String yearLevel, String gender)
    {
        this.firstName = firstName;
        this.lastName = lastName;
        this.course = course;
        this.yearLevel = yearLevel;
        this.gender = gender;
    }

    static ArrayList<Student> students = new ArrayList<Student>();


Solution 1:[1]

You need to compare the one property; also you can use a for-each loop to simplify the code

for(Student s : Student.students){
    if(s.getName().equals(searchKey))
        System.out.print(s);
}

Note :

When you use a condition Student.students.contains(searchKey) in a loop, and it doesn't use the iteration variable that means there is a problem

Solution 2:[2]

You haven't defined what 'contains' means here but I'm going to assume that it means a Student contains the key if it appears as a substring in any of its String members. So let's start with a method that does that. We can define this as part of the Student class itself.

public class Student {
  .... other stuff ....
  /**
   * Return true if any of the properties of this Student
   * contain the given substring, false otherwise
   */
  public boolean contains(String s) {
    // consider addressing null cases - omitting for simplicity
    return firstName.contains(s) ||
      lastName.contains(s) ||
      course.contains(s) ||
      yearLevel.contains(s) ||
      gender.contains(s);
  }
}

Now you can iterate over your List and invoke this method to find the matches. Note that you need to handle the case that multiple Students may match a given search key (or none may match). So I would suggest collecting the results in a separate List. One does not generally iterate over Lists via the index. This example uses an enhanced for-loop (aka for-each).

public List<Student> findMatches(List<Student> students, String key) {
  List<Student> found = new ArrayList<>();
  for (Student s : students) {
    if (s.contains(key)) {
      found.add(s);
    }
  }
  return found;
}

This is a good case for using the Stream API.

public List<Student> findMatches(List<Student> students, String key) {
  return students.stream()
      .filter(s -> s.contains(key))
      .collect(Collectors.toList());
}

Solution 3:[3]

You already know comparing Object to String makes no sense. So, most probably what you are trying to do is check if any of the attributes of your Student object(name/course/year etc) has a value that matches your search key. To do that you need to convert your object into a String.

Add a toString method to your Student class which will look something like this:

public String toString() {
    return "Student [firstName=" + firstName + ", lastName=" + lastName + ", course=" + course + ", yearLevel="
            + yearLevel + ", gender=" + gender + "]";
}

Then, look for your searchKey in the string representation of your objects while iterating.

for(int x = 0; x < students.size(); x ++){
        if(students.get(x).toString().contains(searchKey))
            System.out.print(students.get(x).toString());
    }

Edit: As rightly pointed out by Jon Skeet in the comments, the default toString method will generate incorrect results, a custom implementation should be used to convert the object to String.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 azro
Solution 2 vsfDawg
Solution 3