JDK8
lambda :简化代码
lambda λ 组成 :
- 逗号隔开的参数列表 (x,x,x) ()
 - 箭头符号 ->
 - 方法体 (λ代码块)
 
示例
package lambda;
/* * Created by 颜群 */
public class Demo01 {
   
    public static void test01(){
   
        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                System.out.println("run....");
            }
        }).start(); 
    }
    public static void test02(){
   
        new Thread(
// () -> { System.out.println("run...."); }
             ()  ->  System.out.println("run....")
        ).start(); ;
    }
    public static void main(String[] args) {
   
// test01() ;
          test02() ;
    }
}
          new Thread(
                ()  ->  System.out.println("run....")
        ).start(); ;
  以上述为例, new Thread( )中是一个接口、抽象类。但是为了避免 不能区分 lambda到底是重写的哪个方法,语法上lambda要求 重写的 接口、抽象类中 有且只能有一个 抽象方法。
仔细观察,lambda重写的接口、抽象类中 会标识一个@FunctionalInterface,称为函数式接口。
函数式接口:标注@FunctionalInterface,有且只有一个 抽象方法。
lambda表达式重写的 必须是 函数式接口(或者 只有一个抽象方法的抽象类)
函数式接口要注意以下几点:
- 即使没有标注@FunctionalInterface,但是只有一个抽象方法,也称之为函数式接口
 - 特殊情况:如果某个接口中有多个抽象方法,但只有1个抽象方法是本接口新定义的,其他抽象方法和Object中已有的方法重复,那么该接口仍然是函数式接口。
 
package lambda;
/* * Created by 颜群 */
@FunctionalInterface
public interface MyInterface  {
   //everything is an Object
    public abstract void a() ;//本接口新定义的抽象
    public abstract String toString() ;//和Object中重名(实际会调用Object中的toString())
    public abstract boolean equals(Object obj) ;//和Object中重名
    //重点:toString()和equals()看似是抽象方法,实则是 有方法体的具体方法
}
class MyInterfaceImpl implements  MyInterface{
   
    @Override
    public void a() {
   
        System.out.println("a...");
    }
}
class TestMyInterface{
   
    public static void main(String[] args) {
   
        MyInterfaceImpl impl = new MyInterfaceImpl();
        impl.a();//
        impl.equals("")  ;//
        impl.toString();//
    }
}
  MyInterface中的a()方法是 自己定义的,而其他equals()、toString()方法可以理解为 从Object中继承而来,因此 MyInterface虽然显示了3个抽象,但其实只有1个抽象。
四大核心函数式接口
() { return }
函数式接口从哪来?
-  
JDK自带 (很多存在于java.util.function包中)
-  
有参,无返回值 (消费型)
 
@FunctionalInterface
public interface Consumer {void accept(T t); ...}
- 无参,有返回值(供给型) ```java -  
 
@FunctionalInterface
 public interface Supplier {  
  T get();
  }
 ```
- 有参,有返回值 (函数型)
 
@FunctionalInterface
public interface Function<T, R> {
   
    R apply(T t);
    ...
}
  - 断言式接口
 
@FunctionalInterface
public interface Predicate<T> {
   
   boolean test(T t);
   ...
}
  lambda表达式的使用方式
方式一
 函数式接口 引用名 = lambda表达式 ;
 Predicate p = num -> num < 10 ;
//断言式 
public static void test01(){
   
        // boolean test(T t);
        Predicate<Integer> p = (num) ->  {
   return num < 10;} ;
        //Predicate<Integer> p = num -> num < 10 ;//等价写法
  			boolean flag = p.test(3);
        System.out.println(flag);
    }
  自定义函数式接口使用
 //自己创建的函数式接口
//自定义
@FunctionalInterface
public interface MyMath {
   
    int add(int n1,int n2);
}
public static void test02(){
   
        //相当于将 MyMath中的add()方法进行了具体的实现
// MyMath math = (int n1,int n2) -> { return n1+n2 ;} ;
  // Lambda自带类型推断机制,因此参数的类型,可以省略
        MyMath math =  (n1,n2) -> {
     return  n1+n2 ;} ;
        int result = math.add(34,23);
        System.out.println(result);
    }
//main中调用
  示例
package lambda.Demo01;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public  class Demo02 {
   
    public static void test03(){
   
        //消费性
        //相当于实现了 Consumer 中的void accept(T t);
        Consumer<String> c = (x)->{
   System.out.println("吃"+x);};
        c.accept("苹果");
    }
    public static  void test04(){
   
        //供给型
        Supplier<Integer> supplier = ()->  (int)(Math.random()*9000+1000);
        System.out.println(supplier.get());
    }
    public static void test05(){
   
      //函数型
        Function<String,String> function = (s)->s.toUpperCase();
        String a =  function.apply("hello world");
        System.out.println(a);
    }
    public static void main(String[] args) {
   
        test03();//吃苹果
        test04();//四位随机数
        test05();//HELLO WORLD
    }
}
  方式二
        new Thread(
                ()  ->  System.out.println("run....")
        ).start(); ;
  将lambda表达式所代表的函数式接口,作为一个方法的参数存在。
理解:方法B( 方法A ):函数式编程。scala javascript本身就支持函数式编程。
形式:方法( 函数式接口 )
package lambda;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class Demo02 {
   
    public static void test06(){
   
        String result = upper( (x)-> x.toUpperCase()  ,"hello");
        System.out.println(result);
    }
                                              // fun:函数的逻辑 ,str:hello
    public static String upper( Function<String,String> fun ,String str ){
   
        return  fun.apply(str) ;
    }
  
  
    public static void test07(){
   
        myPredicate( (x) -> x>18,10);
    }
    public static void myPredicate(Predicate<Integer> pre,  Integer num   ){
   
        System.out.println(   pre.test( num ) );
    }
  
        public static void main(String[] args) {
   
        test07();
    }
}
  JDK8其他新特性简介
接口 的默认方法与静态方法
在Java 8中,可以使用default关键字在接口中定义默认方法,并提供默认的实现。之后,该接口的所有实现类都会默认地使用该实现方法。当然,实现类也可以对该默认方法进行重写。例如:
public interface MyInterface {
   
   default String myFunction() {
   
       return "hello world";
   }
}
  此外,还可以在接口中定义静态方法,并提供默认实现。例如:
public interface MyInterface {
   
    static String myFunction() {
   
       return "hello world";
    }
}
  方法引用
Java 8还允许使用::来引用一个已经存在的方法,其语法如下:
类名::方法名
注意:只写方法名即可,不需要写括号。
具体地讲,共有以下四种类型的引用。
| 类 型 | 示 例 | 
|---|---|
| 引用静态方法 | ContainingClass::staticMethodName | 
| 引用某个对象的实例方法 | ContainingObject::instanceMethodName | 
| 引用某个类型的任意对象的实例方法 | ContainingType::methodName | 
| 引用构造方法 | ClassName::new | 
        ArrayList<String> list = new ArrayList<>() ;
      // list.add(...); 参数:String,返回值:boolean
        Predicate<String> pre = list::add ;   // pre.test( ):参数:String,返回值:boolean
        pre.test("a") ;
        pre.test("b") ;
        System.out.println(list);
  重复注解
自从Java 5引入了注解以后,注解就被广泛应用于各个框架之中。但Java 5引入的注解存在一个问题:在同一个地方不能多次使用同一个注解。而Java 8就打破了这个限制,引入了重复注解的概念,允许在同一个地方多次使用同一个注解。
在Java 8中使用@Repeatable注解定义重复注解,代码示例如下:
@Repeatable(Authorities.class)
public @interface Authority {
   
    String role();
}
public @interface Authorities {
   
   Authority[] value();
}
public class RepeatAnnotationUseNewVersion {
   
   @Authority(role="Admin")
   @Authority(role="Manager")
   public void doSomeThing(){
    }
}
  在创建重复注解Authority时,加上@Repeatable并指向用于存储的注解Authorities。之后,在使用的时候,就可以重复使用Authority注解。
其他
Java 8 还提供了Nashorn引擎便于在JVM上运行JavaScript代码,提供了新的Date API,提供了对高并发的新支持,类依赖分析器jdeps……
rface Authorities {  
 Authority[] value();
 }
public class RepeatAnnotationUseNewVersion {
@Authority(role="Admin")
@Authority(role="Manager")
public void doSomeThing(){ }
  }
在创建重复注解Authority时,加上@Repeatable并指向用于存储的注解Authorities。之后,在使用的时候,就可以重复使用Authority注解。
### 其他
Java 8 还提供了Nashorn引擎便于在JVM上运行JavaScript代码,提供了新的Date API,提供了对高并发的新支持,类依赖分析器jdeps……

京公网安备 11010502036488号