重构 Java 8 流代码 - 重复代码

Refactoring Java 8 stream code - duplication of code

我有两个几乎相同的方法:

public String find(Query query) {
        return PRODUCT.stream()
                .filter(byName(query.getName()))
                .filter(byCount(query.getNumber()))
                .map(getValueOf(query.getName()))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException());
    }

第二个:

public String findSpecial(Query query) {
        return SPECIAL_PRODUCTS.stream()
                .filter(byName(query.getName()))
                .filter(byCount(query.getNumber()))
                .filter(byIsDoubled(query.isDoubled()))
                .map(getValueOf(query.getName()))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException());
    }

所以区别仅在于第 .filter(byIsDoubled(query.isDoubled())).

有没有不重复方法体的好方法?

您可以这样做:

SPECIAL_PRODUCTS.stream().filter(findConditional(query)).map(getValueOf(query.getName()))
                    .findFirst()
                    .orElseThrow(() -> new IllegalArgumentException());



public static Predicate<String> findConditional(Query query) {
        List<Predicate<String>> l = new ArrayList<>();
        Predicate<String> defaultPredicate = s -> true;
        l.add(byName(query.getName()));
        l.add(byCount(query.getNumber()));
        if (query.isDoubled()) {
            l.add(byIsDoubled(query.isDoubled()));
        }
        return l.stream().reduce(defaultPredicate, (predicate1, predicate2) -> predicate1.and(predicate2));
    }