java - 将函数传递到 Java 8 中 Stream 的过滤器方法中

标签 java java-8 stream predicate method-reference

我想使用流对象上的 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);
}

对该方法的调用如下所示:

.filter(compare(Utilisateur::getIndividuIde, String::contains, libelleFilter.getFilterSingleValue().toUpperCase()))

这是我根据给定的过滤模式过滤列表的函数:

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;
    
}

所以我在这里面临的问题是我不想比较 Utilisateur::getIndividuIde 值这只是我想要比较的真实字符串的信息以下:

Individu individu = individuLightSVC.donneIndividu(utilisateur.getIndividuIde(), null);
String stringToCompare = individu.getPrenom() + " " + individu.getNom()

所以在我创建的比较函数中,我需要这样的东西:

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);
}

我面临的另一个问题是如何否定方法引用谓词String::contains,因为String没有notContains函数,你可以看到我在这一行中将其留空: .filter(compare(Utilisateur::getIndividuIde, String::, libelleFilter.getFilterSingleValue().toUpperCase()))

你愿意帮助我吗?我将不胜感激任何帮助。

第二个问题的解决方案:

感谢@Holger评论,对String::contains的否定可以通过否定我从compare函数获得的谓词来完成:

.filter(compare(Utilisateur::getIndividuIde, String::contains, libelleFilter.getFilterSingleValue().toUpperCase()).negate())

最佳答案

当类型应该是 String 时,您不能使用类型参数。所以只需删除 <V>并使用String 。然后,您写入方法的代码必须放置在 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);
    };
}

可以使用例如来完成否定((BiPredicate<String,String>)String::contains).negate() ,但是否定具有相同效果的结果谓词要简单得多,例如

.filter(compare(Utilisateur::getIndividuIde, String::contains,
        libelleFilter.getFilterSingleValue().toUpperCase()).negate()‌​)

关于java - 将函数传递到 Java 8 中 Stream 的过滤器方法中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46686072/

相关文章:

c - freopen() 和流的奇怪行为

java 泛型 : compiler error not shown in eclipse

java - 为 Java 8 流编写单元测试

c# - 为什么 BinaryWriter 在处理时关闭外部 Stream,以及如何防止这种情况发生? (.NET C#)

java - 如何通过键集从哈希表中获取所有列表

java - 更改 java 8 默认方法的可见性

node.js - 将 async.js 与 node.js 流一起使用

java - Android 声明一个变量

java - "for loop"仅循环一次或两次。如果是更好的选择吗?

java - OpenCV4 中似乎缺少 Imgproc.unactor()