Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java函数中适当地组合谓词和函数?_Java_Lambda_Java 8_Method Reference_Functional Interface - Fatal编程技术网

如何在Java函数中适当地组合谓词和函数?

如何在Java函数中适当地组合谓词和函数?,java,lambda,java-8,method-reference,functional-interface,Java,Lambda,Java 8,Method Reference,Functional Interface,其目的是创建可在流筛选器中使用的新谓词: myCollectionOfElement .stream() .filter( MyStaticHelperClass.compose(MyStaticHelperClass.getSubElement1OfTheElement(),MyStaticHelperClass.getPredicate1OnSubElement1())) .sorted(MyStaticHelperClass.getOtherSubElement().reverse

其目的是创建可在流筛选器中使用的新谓词:

myCollectionOfElement
.stream()
.filter(
    MyStaticHelperClass.compose(MyStaticHelperClass.getSubElement1OfTheElement(),MyStaticHelperClass.getPredicate1OnSubElement1()))
.sorted(MyStaticHelperClass.getOtherSubElement().reversed())
.limit(10)
.collect(Collectors.toList())
getSubElement1OfTheElement()
返回
函数
(E包含一个S属性)
getPredicate1OnSubElement1()
返回
Predicate

我使用静态函数公开方法引用和函数。 之所以这样做,是因为流是在速度模板中调用的,而此上下文不支持lambda语法和方法引用。 我不想为所有可能的组合创建静态函数,所以我真的希望它们是可组合的

例如,在这里,我不希望有一个静态的
getpredicate1onelements检查subelement1()上的属性1
,因为我可以编写
getSubElement1OfTheElement()
getPredicate1OnSubElement1()

所以我需要一个compose函数:

// 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
//返回通过对函数结果应用谓词谓词构造的新谓词
公共静态谓词组合(函数、谓词)
//最直观的:lambda
返回值->谓词.test(function.apply(value));
//使用方法引用
返回函数。然后(谓词::测试)::apply;
//predicate.compose不可用,因为谓词接口不扩展函数接口
灵感来自

//逐步使用变量
函数谓词函数=谓词::测试;
//一种@FunctionInterface隐式“转换”?谓词->函数。
//安全吗?
函数composed=Function.and(谓词函数::应用);
返回:应用;

编辑:

这被称为演员阵容:

//my compose的实现也可以是这样一个丑陋的一行:
return((函数)谓词::test).compose(函数)::apply;
因此,我们无法使用任何函数接口(在我的例子中是函数和谓词)实现通用组合函数,因为每个接口的抽象方法名称不同(在我的例子中是测试和应用)。
我同意

总之,我真正需要的是两个静态函数,一个将谓词转换为函数,另一个则相反。每个谓词都将用作一个函数,最后的操作将组合函数转换为谓词,以便与过滤器函数的参数类型匹配

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;
}
公共静态函数谓词函数(谓词谓词){
返回谓词::test;
}
公共静态谓词函数topredicate(函数函数){
返回函数::apply;
}

对吗?

如果是这样,是否有兴趣释放函数签名中的边界?

我回答自己的问题

使用lambda:

value -> predicate.test(function.apply(value));
或者,如果您确实想要/必须编写一个compose函数,则签名必须类似于:

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

公共静态谓词组合(函数、谓词我认为最好的方法是使用布尔组合方法
谓词
提供:
。例如

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);
private谓词startsWith(字符串前缀){
返回s->s.startsWith(前缀);
}
私有谓词endsWith(字符串后缀){
返回s->s.endsWith(后缀);
}
“Foo”、“Fuz”、“Doo”、“Fo”流
.过滤器(以“F”开头,以“o”结尾)
.forEach(System.out::println);

你能解释一下你想要实现什么吗?JDK没有内置这个功能的原因是,只需显式编写lambda通常比较简单。@JacobG。我编辑了我的文章来描述上下文。构建器模式如何?@Antoniossss你是指一个新的fluent类,一个接一个地使用谓词还是函数?检查类型和组合它们?这似乎比我需要的要雄心勃勃得多,但可能很有趣。我只想验证我的组合函数是否正确并且在所有情况下都能工作。
public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<? super S> predicate)
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);