有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java8中将函数传递到流的过滤方法

我想使用streamed对象上的String methods引用过滤列表,为此我创建了以下比较函数:

<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 comment,对String::contains的否定可以通过否定我从compare函数得到的谓词来完成:

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


共 (1) 个答案

  1. # 1 楼答案

    当类型应为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()‌​)