1

I have two methods which are nearly the same:

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

and second:

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

so the difference is only line .filter(byIsDoubled(query.isDoubled())).

Is there a good way to not duplicate methods body?

4
  • Sometimes duplicate some lines is not bad. Commented Oct 20, 2020 at 9:13
  • @YCF_L But I am duplicating 5 lines and only adding filter. It doesn't looks good for me Commented Oct 20, 2020 at 9:15
  • You can design something like filter(!isSpecial || byIsDoubled(query.isDoubled())) which return true if isSpecial is false and pass like find(Query query, boolean isSpecial) though I agree with @YCF_L and sometimes clean code is better than making complex to remove duplicate lines. Commented Oct 20, 2020 at 9:26
  • Do like this: public String find(Query query, List<Product> list,List<Predicate<Product>> predicates){ return list.stream().filter(product -> predicates.stream() .allMatch(productPredicate -> productPredicate.test(product))) .map(getValueOf(query.getName())) .findFirst() .orElseThrow(IllformedLocaleException::new); } Commented Oct 20, 2020 at 10:18

1 Answer 1

1

You can do something like:

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));
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.