我有一个这样的电影课:
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());
以及此(只需插入filter()):
public boolean tFilter(String filter){
return this.getTranslation().toLowerCase().contains(filter.toLowerCase());
}
我最近开始使用lambda和Stream API。在我们大学的课程中,没有提到流。所以我决定我自己开始。新手。
答案 0 :(得分:2)
您不能这样做,因为:
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中不存在方法的“部分应用程序”之类的东西。 (如果存在的话,那太酷了……)