[英]Passing a function into the Stream's filter method in Java 8
I want to filter a list using String methods reference on the streamed object, for that I created the following compare function: 我想在流对象上使用String方法引用来过滤列表,为此,我创建了以下比较函数:
<V, C, P> Predicate<? super P> compare(Function<P, V> valueFunction, BiPredicate<V, C> matchPredicate, C value) {
return p -> matchPredicate.test(valueFunction.apply(p), value);
}
And a call to that method look like this: 对该方法的调用如下所示:
.filter(compare(Utilisateur::getIndividuIde, String::contains, libelleFilter.getFilterSingleValue().toUpperCase()))
This is the function where I filter the list depending on the given filter mode: 这是我根据给定的过滤模式过滤列表的函数:
public List<Utilisateur> listUtilisateur(FilterDTO libelleFilter) {
List<Utilisateur> list = utilisateurDAO.listUtilisateur();
switch (libelleFilter.getOperator()) {
case TEXT_CONTAINS:
list = list.stream()
.filter(compare(Utilisateur::getIndividuIde, String::contains, libelleFilter.getFilterSingleValue().toUpperCase()))
.collect(Collectors.toList());
break;
case TEXT_START_WITH:
list = list.stream()
.filter(compare(Utilisateur::getIndividuIde, String::startsWith, libelleFilter.getFilterSingleValue().toUpperCase()))
.collect(Collectors.toList());
break;
case TEXT_DIFFERENT:
list = list.stream()
.filter(compare(Utilisateur::getIndividuIde, String::, libelleFilter.getFilterSingleValue().toUpperCase()))
.collect(Collectors.toList());
break;
case TEXT_END_WITH:
list = list.stream()
.filter(compare(Utilisateur::getIndividuIde, String::endsWith, libelleFilter.getFilterSingleValue().toUpperCase()))
.collect(Collectors.toList());
break;
case TEXT_EQUALS:
list = list.stream()
.filter(compare(Utilisateur::getIndividuIde, String::equals, libelleFilter.getFilterSingleValue().toUpperCase()))
.collect(Collectors.toList());
break;
default:
break;
}
return list;
}
So the problem I'm facing here is that I don't want to compare the Utilisateur::getIndividuIde
value this is just an information for the real string I want to compare which I get using the following : 所以我在这里面临的问题是我不想比较
Utilisateur::getIndividuIde
值,这只是我想比较的真实字符串的信息,我可以使用以下方法得到它:
Individu individu = individuLightSVC.donneIndividu(utilisateur.getIndividuIde(), null);
String stringToCompare = individu.getPrenom() + " " + individu.getNom()
So in the compare function I've created, I need something like this : 因此,在我创建的compare函数中,我需要这样的东西:
private <V, C, P> Predicate<? super P> compare(Function<P, V> valueFunction, BiPredicate<V, C> matchPredicate, C value) {
// Here I want to replace X with the string value of Utilisateur::getIndividuIde
Individu individu = individuLightSVC.donneIndividu(X, null);
String stringToCompare = individu.getPrenom() + " " + individu.getNom();
// Here I want to use stringToCompare instead of valueFunction.apply(p)
return p -> matchPredicate.test(valueFunction.apply(p), value);
}
Another issue I'm facing is how to negate the method reference predicate String::contains
since String
has no notContains
function, you can see that I left it empty in this line : .filter(compare(Utilisateur::getIndividuIde, String::, libelleFilter.getFilterSingleValue().toUpperCase()))
我面临的另一个问题是如何否定方法引用谓词
String::contains
因为String
没有notContains
函数,您可以看到我在这一行.filter(compare(Utilisateur::getIndividuIde, String::, libelleFilter.getFilterSingleValue().toUpperCase()))
其留空: .filter(compare(Utilisateur::getIndividuIde, String::, libelleFilter.getFilterSingleValue().toUpperCase()))
Would you help me? 你能帮我吗? I would appreciate any help.
我将不胜感激任何帮助。
Thanks to @Holger comment, the negation on String::contains
can be done by negating the predicate I get from compare
function : 感谢@Holger评论,对
String::contains
的否定可以通过否定我从compare
函数获得的谓词来完成:
.filter(compare(Utilisateur::getIndividuIde, String::contains, libelleFilter.getFilterSingleValue().toUpperCase()).negate())
You can't use a type parameter, when the type is supposed to be a String
. 当类型应该是
String
时,不能使用类型参数。 So just drop <V>
and use String
. 因此,只需删除
<V>
并使用String
。 Then, the code you have written into the method has to be placed inside the lambda expression to be executed each time the function is evaluated: 然后,您写入该方法的代码必须放置在lambda表达式中,以在每次评估该函数时执行:
private <C, P> Predicate<P> compare(
Function<P, String> valueFunction,
BiPredicate<? super String, C> matchPredicate, C value) {
return p -> {
Individu individu = individuLightSVC.donneIndividu(valueFunction.apply(p), null);
String stringToCompare = individu.getPrenom() + " " + individu.getNom();
return matchPredicate.test(stringToCompare, value);
};
}
Negating can be done using, eg ((BiPredicate<String,String>)String::contains).negate()
, but it's much simpler to just negate the resulting predicate which has the same effect, eg 求反可以使用
((BiPredicate<String,String>)String::contains).negate()
,但((BiPredicate<String,String>)String::contains).negate()
结果具有相同效果的谓词就求反要简单得多,例如
.filter(compare(Utilisateur::getIndividuIde, String::contains,
libelleFilter.getFilterSingleValue().toUpperCase()).negate())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.