美文网首页
[Java8]Java8 lambda表达式学习

[Java8]Java8 lambda表达式学习

作者: 骊骅 | 来源:发表于2017-04-13 12:50 被阅读139次

    0x00 例子

    1、 用lambda表达式实现Runnable

    import java.util.Arrays;
    
    /**
     * Created by haicheng.lhc on 10/04/2017.
     *
     * @author haicheng.lhc
     * @date 2017/04/10
     */
    public class Test {
        public static void main(String[] args) {
    //        java8之前
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Before Java8, too much code for too little to do");
                }
            }).start();
    //      java8之后
            new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
        }
    }
    
    

    输出结果:

    2、使用lambda表达式对列表进行迭代

    import java.util.Arrays;
    import java.util.List;
    
    /**
     * Created by haicheng.lhc on 10/04/2017.
     *
     * @author haicheng.lhc
     * @date 2017/04/10
     */
    public class Test {
        public static void main(String[] args) {
    
            // Java 8之前:
            List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
            for (String feature : features) {
                System.out.println(feature);
            }
    
            // Java 8之后:
            List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
            features.forEach(n -> System.out.println(n));
    
            // 使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示,
            features.forEach(System.out::println);
        }
    }
    
    

    3、使用lambda表达式和函数式接口Predicate

    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Predicate;
    
    /**
     * Created by haicheng.lhc on 13/04/2017.
     *
     * @author haicheng.lhc
     * @date 2017/04/13
     */
    public class TT {
    
        public static void main(String args[]) {
            List<String> languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");
    
            System.out.println("Languages which starts with J :");
            filter(languages, (str) -> str.startsWith("J"));
    
            System.out.println("Languages which ends with a ");
            filter(languages, (str) -> str.endsWith("a"));
    
            System.out.println("Print all languages :");
            filter(languages, (str) -> true);
    
            System.out.println("Print no language : ");
            filter(languages, (str) -> false);
    
            System.out.println("Print language whose length greater than 4:");
            filter(languages, (str) -> str.length() > 4);
        }
    
        public static void filter(List<String> names, Predicate<String> condition) {
            for (String name : names) {
                if (condition.test(name)) {
                    System.out.println(name + " ");
                }
            }
        }
    }
    
    

    其中的filter可以实现的更加优雅

      public static void filter(List<String> names, Predicate<String> condition) {
            names.stream().filter((name) -> (condition.test(name))).forEach((name) -> {
                System.out.println(name + " ");
            });
        }
    

    4、通过过滤创建一个String列表

    过滤是Java开发者在大规模集合上的一个常用操作,而现在使用lambda表达式和流API过滤大规模数据集合是惊人的简单。流提供了一个 filter() 方法,接受一个 Predicate 对象,即可以传入一个lambda表达式作为过滤逻辑。下面的例子是用lambda表达式过滤Java集合,将帮助理解

    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    /**
     * Created by haicheng.lhc on 13/04/2017.
     *
     * @author haicheng.lhc
     * @date 2017/04/13
     */
    public class T2 {
        public static void main(String[] args) {
            List<String> strList = Arrays.asList("Java", "Scala", "C", "Haskell", "Lisp");
            // 创建一个字符串列表,每个字符串长度大于2
            List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());
            System.out.printf("Original List : %s %n filtered list : %s %n", strList, filtered);
        }
    }
    
    
    

    0x01 lambda表达式语法

    (params) -> expression
    (params) -> statement
    (params) -> { statements }

    如果只有一个参数,可以不写()

    0x02 lambda表达式和要点

    • lambda表达式仅能放入如下代码:预定义使用了 @Functional 注释的函数式接口,自带一个抽象函数的方法,或者SAM(Single Abstract Method 单个抽象方法)类型。这些称为lambda表达式的目标类型,可以用作返回类型,或lambda目标代码的参数。例如,若一个方法接收Runnable、Comparable或者 Callable 接口,都有单个抽象方法,可以传入lambda表达式。类似的,如果一个方法接受声明于 java.util.function 包内的接口,例如 Predicate、Function、Consumer 或 Supplier,那么可以向其传lambda表达式。
    • lambda表达式内可以使用方法引用,仅当该方法不修改lambda表达式提供的参数。本例中的lambda表达式可以换为方法引用,因为这仅是一个参数相同的简单方法调用。
    list.forEach(n -> System.out.println(n)); 
    list.forEach(System.out::println);  // 使用方法引用
    

    若对参数有任何修改,则不能使用方法引用,而需键入完整地lambda表达式,如下所示:

    list.forEach((String s) -> System.out.println("*" + s + "*"));
    
    • lambda内部可以使用静态、非静态和局部变量,这称为lambda内的变量捕获。
    • Lambda表达式在Java中又称为闭包或匿名函数
    • Lambda方法在编译器内部被翻译成私有方法,并派发 invokedynamic 字节码指令来进行调用。
    • lambda表达式有个限制,那就是只能引用 final 或 final 局部变量,这就是说不能在lambda内部修改定义在域外的变量。如下代码会编译报错
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    /**
     * Created by haicheng.lhc on 13/04/2017.
     *
     * @author haicheng.lhc
     * @date 2017/04/13
     */
    public class T2 {
        public static void main(String[] args) {
            List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
            int factor = 2;
            primes.forEach(element -> { factor++; });
        }
    }
    
    

    0x03 函数式开发

    0x04 函数接口

    • lambda表达式的目标是函数接口。所以我们要了解一下啥是函数接口
    • 学习资料
    • 函数接口指的是只有一个函数的接口,这样的接口可以隐式转换为Lambda表达式。java.lang.Runnablejava.util.concurrent.Callable是函数式接口的最佳例子
    • Java 8 提供了一个特殊的注解@FunctionalInterface来标明一个接口是函数接口
    package java.lang;
    
    /**
     *
     * @author  Arthur van Hoff
     * @see     java.lang.Thread
     * @see     java.util.concurrent.Callable
     * @since   JDK1.0
     */
    @FunctionalInterface
    public interface Runnable {
        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         */
        public abstract void run();
    }
    

    相关文章

      网友评论

          本文标题:[Java8]Java8 lambda表达式学习

          本文链接:https://www.haomeiwen.com/subject/qravattx.html