1

I am writing below code but it seems to be awkward. Could it be written better? Finally the code has to create a predicate consisted of list of predicates with OR condition.

First predicate, it shoould be appended to list of predicates

Predicate<SomeDto> p1 = t -> StringUtils.isBlank(t.getColor());

List of predicates from someListOfColors

List<Predicate<SomeDto>> collect = Arrays.stream(somelistOfColors)
            .map(ta -> {
                Predicate<SomeDto> p2 = t -> t.getColor().equals(ta.getCode());
                return p2;
            }).collect(Collectors.toList());

All of predicates should be connected with OR condition

or(p1, collect.toArray(new Predicate[collect.size()]));

Method for OR condition

private Predicate<SomeDto> or(Predicate<SomeDto>... predicates) {
    return s -> Arrays.stream(predicates).anyMatch(t -> t.test(s));
}
ernest_k
  • 44,416
  • 5
  • 53
  • 99
michealAtmi
  • 1,012
  • 2
  • 14
  • 36

2 Answers2

2

You can reduce your stream by composing your predicates:

Predicate<SomeDto> collect = somelistOfColors.stream()
        .map(ta -> t -> t.getColor().equals(ta.getCode()))
        .reduce(a -> false, Predicate::or);

If the stream is empty, you will get a predicate that will fail the test by default. Change the first argument to reduce to change that if desired.

Personally, I'd prefer making a single predicate instance that checks a SomeDto instance against a list of colors. If I understand your code correctly, this should be correct:

Predicate<SomeDto> collect = dto -> somelistOfColors.stream()
               .anyMatch(ta -> dto.getColor().equals(ta.getCode()));
ernest_k
  • 44,416
  • 5
  • 53
  • 99
0

Are you sure that you need predicates? It looks like the code just checks if a list of colors contains SomeDtos code. Therefore it can be replaced with a search

SomeDto dto = //...
Arrays.stream(somelistOfColors)
    .map(color -> color.getCode())
    .anyMatch(t -> t.equals(dto.getColor()));
dehasi
  • 2,644
  • 1
  • 19
  • 31