雖然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); } }