<T> 如何在使用方法引用时在 filter() 中链接谓词?



我有这样的类电影:

public class Movie {    
private int id, duration, publishingYear;
private String title, translation;

public Movie(int id, int duration, int publishingYear, String title, String translation) {
super();
this.id = id;
this.duration = duration;
this.publishingYear = publishingYear;
this.title = title;
this.translation = translation;
}
public Predicate<Movie> titleFilter(String filter){
return m -> m.getTitle().toLowerCase().contains(filter.toLowerCase());
}
public Predicate<Movie> translationFilter(String filter){
return m -> m.getTranslation().toLowerCase().contains(filter.toLowerCase());
}
}

如何在使用方法引用时链接谓词筛选器?我知道方法引用可以被视为仅调用特定方法的 lambda 的简写。在我正在阅读的书中,它说:"...方法引用允许您从现有方法实现创建 lambda 表达式..."。那么,为什么我不能这样做呢?

ArrayList<Movie> filteredMovies = (ArrayList<Movie>) app.getMovies().stream()
.filter((Movie::titleFilter(titleFilter)).or(Movie::translationFilter(translationFilter)))
.collect(Collectors.toList());

我知道这将起作用:

Predicate<Movie> titlePredicate = ( m -> m.getTitle().toLowerCase().contains(titleFilter)); 
Predicate<Movie> translationPredicate = ( m -> m.getTitle().toLowerCase().contains(translationFilter)); 
ArrayList<Movie> filteredMovies = (ArrayList<Movie>) app.getMovies().stream()
.filter(titlePredicate.or(translationPredicate))
.collect(Collectors.toList());

以及这个(只需插入到过滤器(( (:

public boolean tFilter(String filter){
return this.getTranslation().toLowerCase().contains(filter.toLowerCase());
}

我最近开始使用lambdas和Stream API。在我们大学的课程中,没有提到流。所以我侦察我自己开始。新手。

你不能这样做,因为:

Movie::titleFilter(titleFilter)

实际上不是方法引用。您正在传入一个参数,这似乎表明您要调用该方法。但是您使用的是::,这使它看起来像一个方法引用。

但是,如果您刚刚执行了Movie::titleFilter,那将是一个方法引用,但无法转换为Predicate<Movie>。如果您显式指定了类型,则可以将其转换为Function<String, Predicate<Movie>>,但这显然不是您想要的。

另请注意,即使您在Movie中有两个这样的方法(这些方法都可以转换为Predicate<Movie>(:

public boolean predicate1() { ... }
public boolean predicate2() { ... }

您不能像这样or它们:

Movie::predicate1.or(Movie::predicate2)

因为Movie::predicate1本身没有类型。这是为了允许将其转换为具有兼容签名的任何功能接口。你必须做:

((Predicate<Movie>)Movie::predicate1).or(Movie::predicate2)

相反。

我认为你的意图是:

// note the static modifiers
public static Predicate<Movie> titleFilter(String filter){
return m -> m.getTitle().toLowerCase().contains(filter.toLowerCase());
}
public static Predicate<Movie> translationFilter(String filter){
return m -> m.getTranslation().toLowerCase().contains(filter.toLowerCase());
}

和:

// note that I am calling the methods which *return* a Predicate<Movie>
ArrayList<Movie> filteredMovies = (ArrayList<Movie>) app.getMovies().stream()
.filter((Movie.titleFilter(titleFilter)).or(Movie.translationFilter(translationFilter)))
.collect(Collectors.toList());

基本上,要进行方法引用,您不能向其传递参数,并且在 Java 中没有方法的"部分应用"这样的事情。(如果它存在就很酷了...

最新更新