java8 (jdk 1.8) 新特性——Lambda

打印 上一主题 下一主题

主题 552|帖子 552|积分 1656

java8 (jdk 1.8) 新特性 ——初步认识 
 
1. 什么是lambda?
目前已知的是,有个箭头  ->  
说一大段官方话,也没有任何意义
我们直接看代码:
之前我们创建线程是这样的
  1. Runnable runnable = new Runnable() {
  2.             @Override
  3.             public void run() {
  4.                 System.out.println("run。。。。。。");
  5.             }
  6.         };
  7.         runnable.run();
复制代码
用lambda:
  1.     Runnable run2 = () -> System.out.println("run。。。。。。");
  2.         run2.run();
复制代码
  
 
 
 
是不是感觉特别离谱,看不懂
别急,还有更离谱的
很常见的一个例子,比较两个整数的大小
之前是这样写的
  1.         Comparator<Integer> myCom = new Comparator<Integer>() {
  2.             @Override
  3.             public int compare(Integer o1, Integer o2) {
  4.                 return Integer.compare(o1, o2);
  5.             }
  6.         };
  7.         int compare = myCom.compare(12, 20);
  8.         int compare1 = myCom.compare(20, 12);
  9.         int compare2 = myCom.compare(20, 20);
  10.         System.out.println(compare);
  11.         System.out.println(compare1);
  12.         System.out.println(compare2);
  13.     }
复制代码
  
用lambda:
  1.         Comparator<Integer> myCom = (o1, o2) -> Integer.compare(o1, o2);
  2.         int compare = myCom.compare(12, 20);
  3.         int compare1 = myCom.compare(20, 12);
  4.         int compare2 = myCom.compare(20, 20);
  5.         System.out.println(compare);
  6.         System.out.println(compare1);
  7.         System.out.println(compare2);
复制代码
  甚至还可以这样 (这个是方法引用)
  1. Comparator<Integer> myCom = Integer::compare;
  2.         int compare = myCom.compare(12, 20);
  3.         int compare1 = myCom.compare(20, 12);
  4.         int compare2 = myCom.compare(20, 20);
  5.         System.out.println(compare);
  6.         System.out.println(compare1);
  7.         System.out.println(compare2);
复制代码
  
第一个数比第二个数    
大 :返回 1
小:返回 -1
相等:返回 0 

 
 
 
刚接触是不是黑人问号,这是什么玩意 
很好,到这,你认识到了lambda 一个缺点,可阅读性差 ,优点 代码简洁
小结:看到 -> lambda           看到 : : 方法引用
 
2.  lamdba 语法
 
 

  • 基本语法 
 1.  箭头操作符  ->  或者叫做lambda 操作符
 2.  箭头操作符将lambda 表达式拆分成两部分 
      左侧:Lambda 表达式的参数列表 
      右侧:Lambda 表达式中所需执行的功能  , 即 Lambda 体
 
 
3. 语法格式
 
语法格式1:无参数,无返回值 

    1. () -> system.out.println("Hello Lambda")   
    复制代码
      
    前边线程的那个例子就是
 
语法格式2:有一个参数 无返回值
  1. (x)-> System.out.println(x);
复制代码
  
若只有一个参数可以省略不写
 
 
  1. x-> System.out.println(x);
复制代码
  
 之前的写法,没有使用lambda
  1. Consumer<String> consumer = new Consumer<String>() {
  2.             @Override
  3.             public void accept(String s) {
  4.                 System.out.println("输出的值:"+s);
  5.             }
  6.         };
  7.         
  8.         consumer.accept("今天不想emo了");
复制代码
  
 使用lambda 
  1. Consumer<String> consumer = s -> System.out.println("输出的值:"+s);
  2.         consumer.accept("今天不想emo了");
复制代码
 
语法格式3:有两个以上参数 ,并且lambda体有多条语句,有返回值
  1.    Comparator<Integer> myCom = (o1, o2) -> {
  2.             System.out.println("其他语句");
  3.             return Integer.compare(o1, o2);
  4.         };
复制代码
  
语法格式4  lambda体中只有一条语句,return 和 大括号都可以省略不写
  1. Comparator<Integer> com  =(x,y)-> Integer.compare(x,y);
复制代码
  有没有发现所有的参数,都没有参数类型,之前我们写函数的时候可是要带上参数类型的
 
语法格式5  lambda表达式参数列表的数据类型可以省略不写,因为JVM编译器通过上下文编译推断出数据类型——类型推断 
 
 
 4. 函数式接口
不管上面哪一种语法格式,lambda都是需要函数式接口的支持
 函数式接口:接口中只有一个抽象方法的接口 称为函数式接口
可以使用一个注解@FunctionalInterface 修饰,可以检查是否是函数式接口
我们可以看看Runnable  接口 的源码
完成的接口类代码如下
 
 
  1. /*
  2. * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
  3. *  ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms
  4. /
  5. package java.lang;
  6. /**
  7. * The Runnable interface should be implemented by any
  8. * class whose instances are intended to be executed by a thread. The
  9. * class must define a method of no arguments called run.
  10. * <p>
  11. * This interface is designed to provide a common protocol for objects that
  12. * wish to execute code while they are active. For example,
  13. * Runnable is implemented by class Thread.
  14. * Being active simply means that a thread has been started and has not
  15. * yet been stopped.
  16. * <p>
  17. * In addition, Runnable provides the means for a class to be
  18. * active while not subclassing Thread. A class that implements
  19. * Runnable can run without subclassing Thread
  20. * by instantiating a Thread instance and passing itself in
  21. * as the target.  In most cases, the Runnable interface should
  22. * be used if you are only planning to override the run()
  23. * method and no other Thread methods.
  24. * This is important because classes should not be subclassed
  25. * unless the programmer intends on modifying or enhancing the fundamental
  26. * behavior of the class.
  27. *
  28. * @author  Arthur van Hoff
  29. * @see     java.lang.Thread
  30. * @see     java.util.concurrent.Callable
  31. * @since   JDK1.0
  32. */
  33. @FunctionalInterface
  34. public interface Runnable {
  35.     /**
  36.      * When an object implementing interface Runnable is used
  37.      * to create a thread, starting the thread causes the object's
  38.      * run method to be called in that separately executing
  39.      * thread.
  40.      * <p>
  41.      * The general contract of the method run is that it may
  42.      * take any action whatsoever.
  43.      *
  44.      * @see     java.lang.Thread#run()
  45.      */
  46.     public abstract void run();
  47. }
复制代码
  
 
 
 
 
 
可以看到这里面就只有一个实现,有一个注解@FunctionalInterface ,说明它就是一个函数式接口,就可以进行lambda简写
 
来看 Comparator 也是一样 有@FunctionalInterface注解
  
 
 
 
 
 
 
 
这里可能就会有疑问,这边明明是有两个抽象方法,怎么是函数式接口呢?
 
别急 !!可以看到这边的注释, 说明这个equals 是 重写了超类 的 equals,本质上是对object 的重写,官方定义这样的抽象方法是不会被定义到 抽象接口数的 ,因此实际上只有一个抽象方法
 
 
 
 
 
 我们自己可以试着定义 函数式接口,很简单
 
 
  1. package com.test1.demo;
  2. @FunctionalInterface
  3. public interface MyFunc {
  4.     void  method();
  5.    
  6. }
复制代码
  
 
 好了,如果,写两个抽象接口会怎样?
 

 
 
 
 
可以看到注解报错了,所以注解用来校验作用就在这
 
 重申一遍,函数式接口:接口中只有一个抽象方法的接口 称为函数式接口
注解只是拿来校验的,方便我们一看就知道这是一函数式接口类,不然还得数个数,验证一下是不是只有一个
 
 现在我也重写 equals ,可以看到并没有报错

 
 
 
 5. java8 中内置四大核心函数式接口 

  •   Consumer 消费型接口 
  1. //Consumer  消费型接口
  2.     @Test
  3.     public void testConsumer() {
  4.         cosumer(1000, (m) -> System.out.println("星期一" + m));
  5.         // 星期一1000.0
  6.     }
  7.     public void cosumer(double m, Consumer<Double> con) {
  8.         con.accept(m);
  9.     }
复制代码
  
 

  •  供给型接口  supplier
  1. @Test
  2.     public void testSupplier() {
  3.         List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
  4.         for (Integer integer : numList) {
  5.             System.out.println(integer); //100 以内10位随机整数
  6.         }
  7.     }
  8.     // 需求:产生指定个数的整数放入集合中
  9.     public List<Integer> getNumList(int num, Supplier<Integer> su) {
  10.         List<Integer> list = new ArrayList<>();
  11.         for (int i = 0; i < num; i++) {
  12.             Integer integer = su.get();
  13.             list.add(integer);
  14.         }
  15.         return list;
  16.     }
复制代码
  
 

  •  Function 函数型接口
  1. @Test
  2.     public void  FunctioStr(){
  3.         String c = getFunction("sbjikss", str -> str.toUpperCase());
  4.         System.out.println(c); //SBJIKSS
  5.         String sub = getFunction("sbjikss", str -> str.substring(2, 3));
  6.         System.out.println(sub);//j
  7.     }
  8.     public  String  getFunction( String str, Function<String,String> f) {
  9.         return f.apply(str);
  10.     }
复制代码
  
 

  • 断言型接口 Predicate  
  1. public  void  tetPre(){
  2.          List<String> list = Arrays.asList("Hello","sss","xxxx","sjjss");
  3.         List<String> list1 = filterStr(list, (pre) -> pre.length() > 3);
  4.         for (String s : list1) {
  5.             System.out.println(s);  // Hello xxxx  sjjss
  6.         }
  7.     }
  8.    //需求:将满足条件字符串放入集合中
  9.     public  List<String>  filterStr(List<String> old , Predicate<String> pre ){
  10.         List<String> newList  = new  ArrayList<>();
  11.         for (String str : old) {
  12.             if (pre.test(str)){
  13.                newList.add(str);
  14.             }
  15.         }
  16.         return newList;
  17.     }
复制代码
  
 感谢阅读!!!
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莫张周刘王

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表