JAVA8新特性

一、接口定义增强

  • 在接口中使用default或static定义普通方法,如下:
  •  1 package com.mdln.com;
     2 
     3 interface IMessage {
     4     public void print();//接口中原本定义的抽象方法
     5 
     6     default void fun() {//使用default定义的普通方法
     7         System.out.println("新特性支持在接口中使用default定义方法");
     8     }
     9 
    10     static void get() {//使用static定义的普通方法
    11         System.out.println("新特性支持在接口中使用static定义方法");
    12     }
    13 
    14     class MessageIpml implements IMessage {
    15         public void print() {
    16             System.out.println("覆写接口中的方法");
    17         }
    18     }
    19 
    20     public static void main(String[] args) {
    21         IMessage im = new MessageIpml();
    22         im.print();
    23         im.fun();
    24         IMessage.get();//调用静态方法
    25     }
    26 }

二、Lamda表达式

       解决匿名内部类代码繁杂而出现,那么

  • 1、首先复习之前的匿名内部类
  •  1 package com.mdln.com;
     2 
     3 interface IMessage {
     4     public void print();
     5 }
     6 
     7 public class TestDemo {
     8     public static void main(String[] args) {
     9         fun(new IMessage() {// 匿名内部类
    10             public void print() {
    11                 System.out.println("hello world");
    12             }
    13         });
    14     }
    15 
    16     public static void fun(IMessage msg) {
    17         msg.print();
    18     }
    19 }
    View Code
  • 2、使用Lamda表达式后的代码:
  •  1 package com.mdln.com;
     2 
     3 interface IMessage {
     4     public void print();
     5 }
     6 
     7 public class TestDemo {
     8     public static void main(String[] args) {
     9         fun(()->System.out.println("hello world"));
    10     }
    11 
    12     public static void fun(IMessage msg) {
    13         msg.print();
    14     }
    15 }
    View Code

    对于Lamda的形式有三种语法:

  • (参数)->单行语句:
  • (参数)->{多行语句}:
  • (参数)->表达式:

         1)带参数单行语句:

  •  1 package com.mdln.com;
     2 
     3 interface IMessage {
     4     public void print(String str);
     5 }
     6 
     7 public class TestDemo {
     8     public static void main(String[] args) {
     9         //首先定义出此表达式接受的内容,单行语句直接进行输出
    10         fun((s)->System.out.println(s));
    11     }
    12 
    13     public static void fun(IMessage msg) {
    14         //设置参数内容
    15         msg.print("hello world");
    16     }
    17 }
    View Code

    2)多行语句

  •  1 package com.mdln.com;
     2 
     3 interface IMessage {
     4     public void print(String str);
     5 }
     6 
     7 public class TestDemo {
     8     public static void main(String[] args) {
     9         // 首先定义出此表达式接受的内容,单行语句直接进行输出
    10         fun((s) -> {
    11             s = s.toUpperCase();
    12             System.out.println(s);
    13         });
    14     }
    15 
    16     public static void fun(IMessage msg) {
    17         // 设置参数内容
    18         msg.print("hello world");
    19     }
    20 }
    View Code

    3)代码中只是一个简单的表达式

  •  1 package com.mdln.com;
     2 
     3 interface IMessage {
     4     public int add(int x, int y);
     5 }
     6 
     7 public class TestDemo {
     8     public static void main(String[] args) {
     9         fun((s1, s2) -> s1 + s2);
    10     }
    11 
    12     public static void fun(IMessage msg) {
    13         System.out.println(msg.add(10, 20));
    14     }
    15 }
    View Code

三、方法引用:为方法设置一个别名,相当于一个方法定义了不同的名字

      JAVA8定义了如下四种形式的引用方法:

      1)引用静态方法:类名称::static方法名称;

      2)引用某个对象的方法:实例化对象::普通方法

      3)引用特定类型的方法:特定类::普通方法

      4)引用构造方法:类名称::new。

    • 引用静态方法举例:在String的方法里有一个valueOf()方法:public static String valueOf(int x)
    •  1 package com.mdln.com;
       2 /**
       3  * 实现方法的引用接口
       4  * @param <P>引用方法的参数类型
       5  * @param <R>引用方法的返回类型
       6  */
       7 interface IMessage<P, R> {
       8     public R zhuanhuan(P p);
       9 }
      10 public class TestDemo {
      11     public static void main(String[] args) {
      12         // 将String.valueOf()方法变为了IMessage接口里的zhuanhuan()方法
      13         IMessage<Integer, String> msg = String::valueOf;
      14         String str = msg.zhuanhuan(1000);
      15         System.out.println(str.replaceAll("0", "9"));
      16     }
      17 }
      View Code
    • 普通方法引用
    •  1 package com.mdln.com;
       2 /**
       3  * 实现方法的引用接口
       4  * @param <P>引用方法的参数类型
       5  * @param <R>引用方法的返回类型
       6  */
       7 interface IMessage<R> {
       8     public R upper();
       9 }
      10 public class TestDemo {
      11     public static void main(String[] args) {
      12         // String类的toUpperCase()方法定义:public String toUpperCase()
      13         //这个方法没有参数,但是有返回值,而且此方法一定要在有实例化对象的时候才可以调用
      14         //"hello"字符串是String类的实例化对象,所以可以直接调用toUpperCase()方法
      15         //将toUpperCase()函数的应用交给了IMessage接口
      16         IMessage<String> msg = "hello"::toUpperCase;
      17         String str = msg.upper();//相当于"hello".toUpperCase()
      18         System.out.println(str);
      19     }
      20 }
      View Code

      如果要实现函数的引用,那么必须要有接口,而且接口里必须只存在一个方法,如果在多一个方法,方法无法进行引用。为了保证接口里只有一个方法,加入注解@FunctionalInterface声明,表示函数式接口

    • 1 /**
      2  * 实现方法的引用接口
      3  * @param <P>引用方法的参数类型
      4  * @param <R>引用方法的返回类型
      5  */
      6 @FunctionalInterface//此为函数式接口,只能定义一个方法
      7 interface IMessage<R> {
      8     public R upper();
      9 }
      View Code
    • 引用特定类型的方法
    • 通常,如果使用“类::方法”引用的一定是类中的静态方法,但是这种形式也可以引用普通方法,String类中有一个方法public int compareTo(String anotherString) 

    •  1 package com.mdln.com;
       2 
       3 /**
       4  * 实现方法的引用接口
       5  * @param <P>引用方法的参数类型
       6  * @param <R>引用方法的返回类型
       7  */
       8 @FunctionalInterface // 此为函数式接口,只能定义一个方法
       9 interface IMessage<P> {
      10     public int compare(P p1, P p2);//理解为前面调用对象,后面传入参数
      11     //public int compareTo(String anotherString),比较形式:字符串1对象.compareTo(字符串2对象),要准备出两个参数
      12 }
      13 
      14 public class TestDemo {
      15     public static void main(String[] args) {
      16         IMessage<String> msg = String::compareTo;
      17         System.out.println(msg.compare("A", "B"));
      18     }
      19 }
      View Code

      与之前相比,方法引用前,不需要再定义对象,而可以理解为将对象定义在了参数上

    • 引用构造方法

    •  1 package com.mdln.com;
       2 /**
       3  * 实现方法的引用接口
       4  * @param <P>引用方法的参数类型
       5  * @param <R>引用方法的返回类型
       6  */
       7 @FunctionalInterface // 此为函数式接口,只能定义一个方法
       8 interface IMessage<C> {
       9     public C create(String t, double p);// 理解为前面调用对象,后面传入参数
      10     // public int compareTo(String
      11     // anotherString),比较形式:字符串1对象.compareTo(字符串2对象),要准备出两个参数
      12 }
      13 class Book {
      14     private String title;
      15     private double price;
      16 
      17     public Book(String title, double price) {
      18         this.title = title;
      19         this.price = price;
      20     }
      21     public String toString() {
      22         return "书名" + this.title + ",价格:" + this.price;
      23     }
      24 }
      25 public class TestDemo {
      26     public static void main(String[] args) {
      27         IMessage<Book> msg = Book::new;// 引用构造
      28         Book book = msg.create("JAVA开发", 9.0);//虽然调用的是create()方法,其实是引用Book类里的构造
      29         System.out.println(book);
      30     }
      31 }
      View Code

四、内建函数式接口

       JDK1.8中的java.util.function包中提供了四个函数式接口,分别如下:

  • 功能性接口(Function): public interface Function<T,R>{public R apply(T t)}:此接口需要接受一个参数,返回一个处理结果
  • 消费性接口(Consumer):public interface Consumer<T>{public void accept(T t)}:只负责接受数据,并不返回处理结果
  • 供给型接口(Supplier):   public interface Supplier<T> {public T get()}:此接口不接收参数,但返回结果
  • 断言型接口(Predicate):public interface Predicate<T>{public boolean test(T t)}:进行判断操作使用
  • 举例1:功能性接口:String有一个方法:public Boolean startsWith(String str)
 1 package com.mdln.com;
 2 
 3 import java.util.function.Function;
 4 
 5 public class TestDemo {
 6     public static void main(String[] args) {
 7         Function<String, Boolean> fun = "##hello"::startsWith;
 8         System.out.println(fun.apply("##"));
 9     }
10 }
View Code
  • 消费型接口:自定义了一个
 1 package com.mdln.com;
 2 
 3 import java.util.function.Consumer;
 4 
 5 class MyDemo {
 6     public void print(String str) {// 此方法只能接收,不能返回
 7         System.out.println(str);
 8     }
 9 }
10 
11 public class TestDemo {
12     public static void main(String[] args) {
13         Consumer<String> cons = new MyDemo()::print;
14         cons.accept("hello");
15     }
16 }
View Code
  • 供给型接口:String类中的一个方法:public String toUpperCase()
 1 package com.mdln.com;
 2 
 3 import java.util.function.Supplier;
 4 
 5 public class TestDemo {
 6     public static void main(String[] args) {
 7         Supplier<String> sup = "hello"::toUpperCase;
 8         System.out.println(sup.get());
 9     }
10 }
View Code
  • 断言型接口:String类中的一个方法:
 1 package com.mdln.com;
 2 
 3 import java.util.function.Predicate;
 4 
 5 public class TestDemo {
 6     public static void main(String[] args) {
 7         Predicate<String> pre = "hello"::equalsIgnoreCase;
 8         System.out.println(pre.test("hello"));
 9     }
10 }
View Code

                

原文地址:https://www.cnblogs.com/wangna----558169/p/6142325.html