Method that can take lists of 2 different types in Java

I want to iterate to through 2 lists and find a value. I’m trying to combine these functions into 1 function, but not sure if possible. Can this be done? Iteration of List< Student > looks something like

for (Student student : studentList){
    if (obj.value() == -1){
        return obj.value();    
}
}

Iteration of List< Teacher > looks like

for (Teacher teacher : teacherList){
    if (obj.val() == -1){
        return obj.value();    
}
}

NOTE: the functions for object A and B retrieve the same value, but they have different function names, hence the .val() vs .value()

Can these functions be combined into 1?

Answer

I’m going to assume you can’t modify the Teacher and Student classes, and make them implement a common interface (or extend a common class) which has the val / value method in it. If you can, then just do that.


You can use generics to handle this for you. A Function should cover what you’re trying to do here:

public <T, P> T get(final Collection<P> people, 
                    final ToIntFunction<P> valGetter,
                    final Function<P, T> resultGetter) {

    for (final P person : people) {
        if (valGetter.applyAsInt(person) == -1) {
            return resultGetter.apply(person);
        }
    }

    // I don't know, do something?  Throw?
    return null;
}

and then invoke it with something like:

final List<Student> students = new ArrayList<>();
get(students, Student::value, Student::name);

final List<Teacher> teachers = new ArrayList<>();
get(teachers, Teacher::val, Teacher::name);

ToIntFunction will take an element of the generic type, and return an int. So for Student we just use Student::value, and for Teacher, use Teacher::val.

I can’t tell if the obj.value(); result is the same type, or comes from a common interface on both types. If it does, then you can add <T, P extends CommonType> in the generic part, and then just call .value() from that. The answer above assumes it doesn’t, and so the resultGetter Function is used to convert your person-type (Teacher or Student) to whatever result type that class gives. I used ::name in the examples above, but replace that with whatever property you want to pull out from them.

Finally, handle the case when none of them match… I don’t know what’s suitable in your case, but throw new ...Exception or return null seem the two most likely candidates.