JDK8新特性詳解(一)

雖然JDK8已經出來了N久,其新特性也在日益改變着咱們的編碼習慣和風格。雖然有些新特性用起來很順手,可是老是傻傻分不清究竟是哪一個版本的。趁今天有時間,咱們就來總結一下,JDK8有哪些能提高咱們開發效率的新特性:java

1、靜態方法的默認方法和靜態方法python

衆所周知,在接口中定義的普通方法都是抽象方法,方法前面默認都會添加 public abstract ,不能有方法實現,須要在接口的實現類中對方法進行具體實現。編程

接口:數組

package com.beck.util;

/**
 * @author 我是七月呀
 * @date 2020/12/18
 */
public interface MethodService {
    /**
     * 抽象方法
     */
    void abstractMethod();

    /**
     * 默認方法
     */
    default void defaultMethod(){
        System.out.println("執行了默認方法");
    }

    /**
     * 靜態方法
     */
    static void staticMethod(){
        System.out.println("執行了靜態方法");
    }

}

實現類:app

package com.beck.util;

/**
 * @author 我是七月呀
 * @date 2020/12/18
 */
public class MethodServiceImpl implements MethodService {

    @Override
    public void abstractMethod() {
        System.out.println("執行了抽象方法");
    }

}

測試類:ide

package com.beck.util;

/**
 * @author 我是七月呀
 * @date 2020/12/18
 */
public class TestMethod {

    public static void main(String[] args) {
        MethodServiceImpl methodService = new MethodServiceImpl();
        methodService.abstractMethod();
        methodService.defaultMethod();
        //調用靜態方法
        MethodService.staticMethod();
        MethodService methodServiceOne = new MethodService() {
            @Override
            public void abstractMethod() {
            }

            @Override
            public void defaultMethod() {
                System.out.println("默認方法是能夠被重寫的");
            }
        };
        methodServiceOne.defaultMethod();
    }
}
 public class Student { 
    private int id;      
     private String name;     
     private String sex;     
     public int getId() {         return id;     }       public void setId(int id) {         this.id = id;     }       public String getName() {         return name;     }       public void setName(String name) {         this.name = name;     }       public String getSex() {         return sex;     }       public void setSex(String sex) {         this.sex = sex;     }       public Student() {     }       public Student(int id, String name, String sex) {         this.id = id;         this.name = name;         this.sex = sex;     }       @Override     public String toString() {         return "Student{" +             "id=" + id +             ", name='" + name + '\'' +             ", sex='" + sex + '\'' +             '}';     } }

總結:一、抽象方法必須重寫,默認方法可選擇性重寫,靜態方法沒法重寫函數式編程

​ 二、抽象方法和默認方法都不能夠經過接口調用,必須經過接口的實現類實例的對象來調用;靜態方法能夠直接經過接口調用,不能夠經過接口的實現類實例的對象來調用函數

2、Lambda表達式測試

Lambda表達式是Java8中很是重要的一個新特性,其基於函數式編程的思想,支持將代碼做爲方法參數進行使 用。能夠把Lambda表達式理解爲經過一種更加簡潔的方式表示可傳遞的匿名函數。
它自己沒有名稱,並且不像方法那樣屬於某一個類,可是能夠有參數列表、代碼體、返回值。使用了Lambda表達 式以後就不須要再去編寫匿名類了優化

Lambda使用規範

Lambda基礎格式

(參數列表) ‐> { 
    方法體      
}

參數列表:即匿名方法的形參
-> :Lambda運算符
方法體:用於執行業務邏輯。能夠是單一語句,也能夠是語句塊。若是是單一語句,能夠省略花括號。當須要返回 值,若是方法體中只有一條語句,能夠省略return,會自動根據結果進行返回。

一、數的Lambda表達式;
()->System.out.println("haha");
二、只有一個參數的Lambda表達式;
x->{
    System.out.println("haha");
    return x;
}
三、有多個參數的Lambda表達式;
(x,y)->{
    System.out.println(x);
    System.out.println(y);
    return x+y;
}
ps:參數列表中參數的數據類型能夠交給JVM根據上下文進行推斷。因此能夠 不用定義類型。
四、多個參數一條語句的Lambda表達式
(x,y) -> x+y;

Lambda使用對比

package com.beck.util.student;
import java.util.ArrayList;
/**
 * @author 我是七月呀
 * @date 2020/12/18
 */
public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("zhangsan");
        list.add("lisi");
        list.add("wangwu");
        list.add("zhaoliu");
        //for循環遍歷
        for (String s : list) {
            System.out.println(s);
        }
        //lambda表達式遍歷
        list.forEach(s -> System.out.println(s));

        //匿名內部類
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("I'm running");
            }
        };
        //lambda表達式
        Runnable runnable1 = () -> System.out.println("I'm running");
    }
}

3、函數式接口

在Java8中爲了讓如今有的函數可以更加友好的使用Lambda表達式,所以引入了函數式接口這個概念。其是一個 僅有一個抽象方法的普通接口。若是聲明多個抽象方法則會報錯。可是默認方法和靜態方法在此接口中能夠定義多 個。 要想自定義一個函數式接口的話,須要在接口上添加 @FunctionalInterface 。

/**
 * @author 我是七月呀
 * @date 2020/12/21
 */
@FunctionalInterface
public interface DemoService {

    void method();
}
/**
 * @author 我是七月呀
 * @date 2020/12/21
 */
public class Demo {
    public static void demo(DemoService demoService){
        demoService.method();
    }

    public static void main(String[] args) {
        demo(()-> System.out.println("hahahah"));
    }

}

4、常見應用

在Java8的類庫設計中,已經引入了幾個函數式接口:Predicate、Consumer、Function、Supplier

一、Predicate使用

Predicate接口是Java8定義的一個函數式接口,屬於java.util.function包下,用於進行判斷操做,內部定義一個 抽象方法test、三個默認方法and,negate,or、一個靜態方法isEqual

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

/**
 * @author 我是七月呀
 * @date 2020/12/21
 */
public class MyPredicateDemo {
    public static List<Student> filter(List<Student> studentList, Predicate<Student> predicate) {
        ArrayList<Student> list = new ArrayList<>();
        studentList.forEach(student ->  {
        if (predicate.test(student)) {
            list.add(student);
        }
    });
        return list;
    }

    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1, "張三", "M"));
        students.add(new Student(2, "李四", "M"));
        students.add(new Student(3, "王五", "F"));
        List<Student> result = filter(students, student -> student.getSex().equals("F"));
        System.out.println(result.toString());
    }
}

二、Consumer使用

Consumer也是JDK8提供的函數式接口,用於進行獲取數據的操做,其內部定義了一個抽象方法accept、一個默 認方法andThen。

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
 * @author 我是七月呀
 * @date 2020/12/21
 */
public class MyConsumerDemo {
public static void foreach(List<String> arrays, Consumer<String> consumer){
    arrays.forEach(s -> consumer.accept(s));
    }
    public static void main(String[] args) {
    List<String> arrays = new ArrayList<>();
    arrays.add("java");
    arrays.add("python");
    arrays.add("go");
    arrays.add("hive");
    foreach(arrays,s -> System.out.print(s+" "));
    }
}

三、Function的使用

Function主要用於進行類型轉換的操做。內部提供一個抽象方法apply、兩個默認方法compose,andThen、一個 靜態方法identity。對於apply方法,它接收一個泛型T對象,並返回一個泛型R的對象。

import java.util.function.Function;
/**
 * @author 我是七月呀
 * @date 2020/12/21
 */
public class MyFunctionDemo {
public static Integer convert(String value, Function<String,Integer> function){
    return function.apply(value);
}
public static void main(String[] args) {
    String value = "22";
    Integer result = convert(value, s -> Integer.parseInt(s) + 22);
    System.out.println(result);
    }
}

四、Supplier 的使用

Supplier也是用來進行值獲取操做,內部只有一個抽象方法get

import java.util.function.Supplier;
/**
 * @author 我是七月呀
 * @date 2020/12/21
 */
public class MySupplierDemo {
    public static Integer getMin(Supplier<Integer> supplier){

        return supplier.get();
    }
    public static void main(String[] args) {
    // 建立數組
    int[] arr = {100,20,50};
        Integer result = getMin(() -> {
            int min = arr[0];
            for (int i : arr) {
                if (i < min) {
                    min = i;
                }
            }
            return min;
        });

        System.out.println(result);
    }
}

5、方法引用

方法引用更近一步的優化了Lambda的使用。它讓代碼感受更加的天然。咱們能夠直接使用 :: 來簡化Lambda表 達式的使用。其使用語法以下:

類名或實例名::方法名
import java.util.ArrayList;
import java.util.Comparator;

/**
 * @author 我是七月呀
 * @date 2020/12/21
 */
public class MyDemo {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<>();
        Student student1 = new Student(2,"張三","M");
        Student student2 = new Student(1,"李四","F");
        students.add(student1);
        students.add(student2);
        students.sort(Comparator.comparing(Student::getId));
        System.out.println(students);
    }
}
相關文章
相關標籤/搜索