簡體   English   中英

如何在 Java 函數中適當地組合 Predicate 和 Function?

[英]How to suitably compose Predicate and Function in a Java function?

目的是創建一個可在流過濾器中使用的新 Predicate :

myCollectionOfElement
.stream()
.filter(
    MyStaticHelperClass.compose(MyStaticHelperClass.getSubElement1OfTheElement(),MyStaticHelperClass.getPredicate1OnSubElement1()))
.sorted(MyStaticHelperClass.getOtherSubElement().reversed())
.limit(10)
.collect(Collectors.toList())

getSubElement1OfTheElement()返回Function<E,S> (E 包含 S 屬性) getPredicate1OnSubElement1()返回Predicate<S>

我使用靜態函數來公開方法引用和函數。 我這樣做是因為在Velocity 模板中調用了流,並且此上下文不支持 lambda 語法和方法引用 我不想為所有可能的組合創建一個靜態函數,所以我真的希望它們是可組合的

例如在這里,我不想有一個靜態的getPredicate1OnElementThatCheckProperty1OnTheSubElement1()因為我可以組合getSubElement1OfTheElement()getPredicate1OnSubElement1()

所以我需要一個撰寫功能:

// returns a new Predicate constructed by applying Predicate predicate on the result of Function function
public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<S> predicate)

// most intuitive : lambda
return value -> predicate.test(function.apply(value));

// with method references
return function.andThen(predicate::test)::apply;
// predicate.compose is not available because Predicate interface doesn't extends Function interface

靈感來自是否有一種方便的方法來創建一個 Predicate 來測試一個字段是否等於給定值?

// step by step with variables
Function <S,Boolean> predicateFunction = predicate::test;
// a kind of @FunctionalInterface implicit "conversion" ? Predicate -> Function.
// is that safe ?

Function <E,Boolean> composed = function.andThen(predicateFunction::apply);
return composed::apply;

編輯 :

它被稱為轉換上下文: https : //docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

// the implementation of my compose can also be this ugly one-liner :
return ((Function <S,Boolean>)predicate::test).compose(function)::apply;

因此,我們不能使用任何函數接口(在我的例子中是 Function 和 Predicate)來實現一個通用的 compose 函數,因為每個接口的抽象方法的名稱都不同(在我的例子中是 test 和 apply)。
我沒問題。

總而言之,我真正需要的是兩個靜態函數,一個將 Predicate 轉換為 Function,另一個則相反。 每個 Predicate 將用作函數,最終操作將組合函數轉換為 Predicate 以匹配過濾器函數的參數類型。

public static <S> Function<S,Boolean> predicateToFunction(Predicate<S> predicate){
    return predicate::test;
}
public static <S> Predicate<S> functionToPredicate(Function<S,Boolean> function){
    return function::apply;
}

那是對的嗎 ?
如果是這樣,是否有興趣釋放函數簽名中的邊界?

我回答我自己的問題。

使用拉姆達:

value -> predicate.test(function.apply(value));

或者,如果你真的想要/必須編寫一個撰寫函數,簽名必須是這樣的:

public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<? super S> predicate)

我認為最好的方法是使用Predicate提供的布爾組合方法: and , or , not 例如,

private Predicate<String> startsWith(String prefix) {
    return s -> s.startsWith(prefix);
}

private Predicate<String> endsWith(String suffix) {
    return s -> s.endsWith(suffix);
}

Stream.of("Foo","Fuz","Doo","Fo")
    .filter(startsWith("F").and(endsWith("o")))
    .forEach(System.out::println);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM