Home > Enterprise >  Method that can take lists of 2 different types in Java
Method that can take lists of 2 different types in Java

Time:09-22

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?

CodePudding user response:

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.

  • Related