I have several methods that are basically all the same except for one method that is called in these methods.
Example:
protected List<DeadlineEntity> getEntityOneDeadlines() {
return deadLineEntityList
.stream()
.filter(m -> getEntityOneDeadlineDbs().stream().anyMatch(p -> m.getDb_4() != null && m.getDb_4().equals(p)))
.collect(Collectors.toList());
}
protected List<DeadlineEntity> getEntityTwoDeadlines() {
return deadLineEntityList
.stream()
.filter(m -> getEntityTwoDeadlineDbs().stream().anyMatch(p -> m.getDb_5() != null && m.getDb_5().equals(p)))
.collect(Collectors.toList());
}
So the only difference is the method getDB()
.
Since I don't want to have this method 10 times, I thought of writing this into a method and then controlling it via the input parameters.
My attempt looks like this:
protected List<DeadLineEntity> getDeadlines(List<Integer> deadLineDbList, Function<<? super T, ?> dbProperty) {
return deadLineEntityList
.stream()
.filter(m -> deadLineDbList.stream().anyMatch(p -> ....))
}
In method anyMatch()
I do not get further.
This is how I would want to use it:
List<DeadlineEntity> list1 = getDeadlines(getEntityOneDeadlineDbs(), EntityOne::getDb_4());
List<DeadlineEntity> list2 = getDeadlines(getEntityTwoDeadlineDbs(), EntityTwo::getDb_5());
What do you think? is this a good approach? What would be the further procedure in the getDeadlines()
method
Just use Supplier
to insert the required instance of the List
and Function
to substitute the getter from DeadlineEntity
to T
compliant with the getEntityXXX
method generic type of the returned List:
protected <T> List<DeadlineEntity> getDeadlines(Supplier<List<T>> dbProperty, Function<DeadlineEntity, T> getter) {
return deadLineEntityList
.stream()
.filter(m -> dbProperty.get()
.stream()
.anyMatch(p -> getter.apply(m) != null &&
getter.apply(m).equals(p)))
.collect(Collectors.toList());
}
List<DeadlineEntity> one = getDeadlines(this::getEntityOneDeadlineDbs, DeadlineEntity::getDb_4);
List<DeadlineEntity> two = getDeadlines(this::getEntityTwoDeadlineDbs, DeadlineEntity::getDb_5);
Edit: To make the code a bit more readable, I'd filter out all p
equal to null
first and then simplify the lambda expression and switch the parameters of the equals
call in the anyMatch
method to be null-safe:
protected <T> List<DeadlineEntity> getDeadlines(Supplier<List<T>> dbProperty, Function<DeadlineEntity, T> getter) {
return deadLineEntityList
.stream()
.filter(m -> dbProperty.get().stream()
.filter(Objects::nonNull)
.anyMatch(p -> p.equals(getter.apply(m))))
.collect(Collectors.toList());
}