Java 8 Streams:简化o1 - >流中的Objects.equals(o1.getSome()。getSomeOther(),o2.getSome()。getSomeOther())

时间:2017-04-27 14:55:34

标签: java java-8 java-stream

给出以下代码:

stream.filter(o1 -> Objects.equals(o1.getSome().getSomeOther(),
                                   o2.getSome().getSomeOther())

怎么可能简化?

是否有一些equals - 实用程序可让您首先提取密钥,就像Comparator.comparing接受密钥提取函数一样?

请注意,代码本身(getSome().getSomeOther())实际上是从架构生成的。

2 个答案:

答案 0 :(得分:2)

编辑:(与同事讨论后再访问:Is there a convenience method to create a Predicate that tests if a field equals a given value?

我们现在已经开始使用以下可重用的功能界面:

@FunctionalInterface
public interface Property<T, P> {

  P extract(T object);

  default Predicate<T> like(T example) {
     Predicate<P> equality = Predicate.isEqual(extract(example));
     return (value) -> equality.test(extract(value));
  }
}

以及以下静态便捷方法:

static <T, P> Property<T, P> property(Property<T, P> property) {
  return property;
}

过滤现在看起来像:

stream.filter(property(t -> t.getSome().getSomeOther()).like(o2))

我之前对此解决方案的喜爱之处在于:它清楚地区分了属性的提取和Predicate本身的创建,并且更清楚地说明了正在发生的事情。

以前的解决方案:

<T, U> Predicate<T> isEqual(T other, Function<T, U> keyExtractFunction) {
  U otherKey = keyExtractFunction.apply(other);
  return t -> Objects.equals(keyExtractFunction.apply(t), otherKey);
}

导致以下用法:

stream.filter(isEqual(o2, t -> t.getSome().getSomeOther())

但如果有人有更好的解决方案,我会更高兴。

答案 1 :(得分:1)

我认为你的问题的方法比答案的方法更具可读性。而且我也认为使用内联lambda是好的,只要lambda简单而简短。

但是,出于维护,可读性,调试和可测试性的原因,我总是将我在lambda(谓词或函数)中使用的逻辑移动到一个或多个方法。在你的情况下,我会这样做:

em.createNamedQuery("Client.findTestWidgetResultList")
  .setParameter(1,parsedList).getResultList();

有了这些方法,你的谓词现在变得微不足道了:

private String setINClauseFromList(List<Long> l){
    StringBuilder sb = new StringBuilder();

    l.parallelStream().forEach( n -> sb.append(n + ","));

    sb.deleteCharAt(sb.lastIndexOf(","));    

    return sb.toString();
}