method reference vs lambda expression

好久不见. 提交于 2020-01-31 18:11:01

问题


I want to replace lambda expression by method reference in the below example :

 public class Example {

        public static void main(String[] args) {
            List<String> words = Arrays.asList("toto.", "titi.", "other");
         //lambda expression in the filter (predicate)
            words.stream().filter(s -> s.endsWith(".")).forEach(System.out::println);
        }
   }

I want to write a something like this :

words.stream().filter(s::endsWith(".")).forEach(System.out::println);

is it possible to transform any lambda expression to method reference.


回答1:


There is no way “to transform any lambda expression to method reference”, but you can implement a factory for a particular target type, if this serves recurring needs:

public static <A,B> Predicate<A> bind2nd(BiPredicate<A,B> p, B b) {
    return a -> p.test(a, b);
}

with this, you can write

words.stream().filter(bind2nd(String::endsWith, ".")).forEach(System.out::println);

but actually, there’s no advantage. Technically, a lambda expression does exactly what you want, there’s the minimum necessary argument transformation code, expressed as the lambda expression’s body, compiled into a synthetic method and a method reference to that synthetic code. The syntax
s -> s.endsWith(".") also is already the smallest syntax possible to express that intent. I doubt that you can find a smaller construct that would still be compatible with the rest of the Java programming language.




回答2:


You can use selectWith() from Eclipse Collections. selectWith() takes a Predicate2 which takes 2 parameters instead of a Predicate. The second parameter to selectWith() gets passed as the second parameter to the Predicate2 every time it's called, once per item in the iterable.

MutableList<String> words = Lists.mutable.with("toto.", "titi.", "other");
words.selectWith(String::endsWith, ".").each(System.out::println);

By default Eclipse Collections is eager, if you want to iterate lazily then you can use asLazy()

words.asLazy().selectWith(String::endsWith, ".").each(System.out::println);

If you can't change from List:

List<String> words = Arrays.asList("toto.", "titi.", "other");
ListAdapter.adapt(words).selectWith(String::endsWith, ".").each(System.out::println);

Eclipse Collections' RichIterable has several other *With methods which work well with method references, including rejectWith(), partitionWith(), detechWith(), anySatisfyWith(), allSatisfyWith(), noneSatisfyWith(), collectWith()

Note: I am a contributor to Eclipse Collections.



来源:https://stackoverflow.com/questions/40215509/method-reference-vs-lambda-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!