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.