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.
