Skip to content
Advertisement

Is there a way to reduce multiple methods as one method with Function as methode parameter?

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

Advertisement

Answer

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());
}
Advertisement