主頁 > 後端開發 > jdk都出到16了8還沒掌握嗎?挽周帶你玩轉java8新特性(建議收藏)

jdk都出到16了8還沒掌握嗎?挽周帶你玩轉java8新特性(建議收藏)

2021-08-09 08:01:02 後端開發

Java 8 新特性

Java 8 (又稱為 jdk 1.8) 是 Java 語言開發的一個主要版本, Oracle 公司于 2014 年 3 月 18 日發布 Java 8 ,它支持函式式編程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等,

在這里插入圖片描述


在本文中我們將圍繞以下五點學習(常用的)新特性,并用實際的例子說明在什么場景下適合使用,

文章目錄

  • Java 8 新特性
  • 友情鏈接
    • 一.Lambda運算式
    • 二.函式式(Funcation)介面
    • 三.方法參考與構造器參考
      • 方法參考
      • 構造器參考
      • 陣列參考
    • 四.Stream API
    • 五.Optional類


友情鏈接

菜鳥教程:點我跳轉Java8新特性菜鳥教程地址

JDK:點我跳轉Jdk8官網下載地址


一.Lambda運算式

Lambda 是一個匿名函式,我們可以把Lambda運算式理解為是一段可以傳遞的代碼,將代碼像資料一樣進行傳遞,使用它可以寫出更簡潔,更靈活的代碼,作為一種更緊湊的代碼風格,使Java的語言表達能力得到了提升,

語法:

(o1,o2) -> Integer.compare(o1,o2);
  • ->:lambda運算子,也叫箭頭運算子
  • -> 左邊:lambda形參串列 (其實就是介面中的抽象方法的形參串列)
  • -> 右邊:lambda體(其實就是重寫的抽象方法的方法體)

案例:

  1. 格式:無引數,無回傳值
    @Test
    public void test(){
        //原寫法
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                System.out.println("無參無回傳值原寫法");
            }
        };
        runnable.run();

        //Lambda運算式寫法
        Runnable lrunnable =()->{System.out.println("無參無回傳值Lambda運算式寫法");};
        lrunnable.run();
    }

在這里插入圖片描述

  1. 格式:Lambda 需要一個引數,但是沒有回傳值
 @Test
    public void test(){
        //原寫法
        Consumer<String> consumer=new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("需要一個引數沒有回傳值,原寫法");

        //Lambda運算式寫法
        Consumer<String> lconsumer =(String s)->{System.out.println(s);};
        lconsumer.accept("需要一個引數沒有回傳值,Lambda運算式寫法");
    }

在這里插入圖片描述

  1. 格式:資料型別可以省略,因為可由編譯器推斷得出,稱為“型別推斷”
    @Test
    public void test(){
        //原寫法
        Consumer<String> consumer=new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("需要一個引數沒有回傳值,原寫法");

        //Lambda運算式寫法
        Consumer<String> lconsumer =(s)->{System.out.println(s);};
        lconsumer.accept("需要一個引數沒有回傳值并且資料型別可以省略, Lambda運算式寫法");
    }

在這里插入圖片描述

  1. 格式:Lambda 若只需要一個引數時,引數的小括號可以省略
    @Test
    public void test(){
        //原寫法
        Consumer<String> consumer=new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("需要一個引數沒有回傳值,原寫法");

        //Lambda運算式寫法
        Consumer<String> lconsumer = s ->{System.out.println(s);};
        lconsumer.accept("需要一個引數沒有回傳值,資料型別可以省略,小括號也可以省略 Lambda運算式寫法");
    }

在這里插入圖片描述

  1. 格式:Lambda 需要兩個或以上的引數,多條執行陳述句,并且可以有回傳值
    @Test
    public void test(){
        //原寫法
        Comparator<Integer> comparator=new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        };
        System.out.println(comparator.compare(1,2));

        //Lambda運算式寫法
        Comparator<Integer> lcomparator=(o1,o2)->{return o1.compareTo(o2);};
        System.out.println(lcomparator.compare(1,2));
    }

在這里插入圖片描述

  1. 格式:當 Lambda 體只有一條陳述句時, return 與大括號都可以省略
    @Test
    public void test(){
        //原寫法
        Comparator<Integer> comparator=new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        };
        System.out.println(comparator.compare(1,2));

        //Lambda運算式寫法
        Comparator<Integer> lcomparator=(o1,o2)-> o1.compareTo(o2);
        System.out.println(lcomparator.compare(1,2));
    }

在這里插入圖片描述
總結:

  • lambda運算式的本質:作為函式式介面的實體
  • -> 左邊 : 如果使用泛型,lambda形參串列的引數型別可以省略(型別推斷),如果lambda形參串列只有一個引數()也可以省略,
  • -> 右邊:lambda體使用一對{}包裹,如果lambda體只有一條執行陳述句(可能是return陳述句),可以省略這一對{}return關鍵字 (如果省略了return關鍵字{}也一定要去掉)

二.函式式(Funcation)介面

如果一個介面中,只宣告了一個抽象方法(可以有多個非抽象方法),則此介面就稱為函式式介面,函式式介面可以被隱式轉換為 lambda 運算式,

學習之前先來看一下JDK 1.8 之前已有的函式式介面 Runnable
在這里插入圖片描述

我們常用的一些介面Callable、Runnable、Comparator等在JDK8中都添加了@FunctionalInterface注解,該注解不是必須的,如果一個介面符合"函式式介面"定義,那么加不加該注解都沒有影響,加上該注解能夠更好地讓編譯器進行檢查,如果撰寫的不是函式式介面,但是加上@FunctionInterface,那么編譯器會報錯,

自定義函式式介面:

/**
 * @author mengzhichao
 * @create 2021-06-06-18:25
 */
@FunctionalInterface
public interface MyInterface {

    void method();
    
}

總結:在Java8中,Lambda運算式就是一個函式式介面的實體,這就是Lambda運算式和函式式介面的關系,也就是說,只要一個物件是函式式介面的實體,那么該物件就可以用Lambda運算式來表示,所以以前用匿名實作類表示的現在都可以用Lambda運算式來寫,

JDK 1.8 新增加的函式介面:

介面描述
BiConsumer<T,U>代表了一個接受兩個輸入引數的操作,并且不回傳任何結果
BiFunction<T,U,R>代表了一個接受兩個輸入引數的方法,并且回傳一個結果
BinaryOperator< T >代表了一個作用于于兩個同型別運算子的操作,并且回傳了運算子同型別的結果
BiPredicate<T,U>代表了一個兩個引數的boolean值方法
BooleanSupplier代表了boolean值結果的提供方
Consumer代表了接受一個輸入引數并且無回傳的操作
DoubleBinaryOperator代表了作用于兩個double值運算子的操作,并且回傳了一個double值的結果,
DoubleConsumer代表一個接受double值引數的操作,并且不回傳結果,
DoubleFunction< R >代表接受一個double值引數的方法,并且回傳結果
DoublePredicate代表一個擁有double值引數的boolean值方法
DoubleSupplier代表一個double值結構的提供方
DoubleToIntFunction接受一個double型別輸入,回傳一個int型別結果,
DoubleToLongFunction接受一個double型別輸入,回傳一個long型別結果
DoubleUnaryOperator接受一個引數同為型別double,回傳值型別也為double ,
Function<T,R>接受一個輸入引數,回傳一個結果,
IntBinaryOperator接受兩個引數同為型別int,回傳值型別也為int ,
IntConsumer接受一個int型別的輸入引數,無回傳值 ,
IntFunction< R >接受一個int型別輸入引數,回傳一個結果 ,
IntPredicate接受一個int輸入引數,回傳一個布林值的結果,
IntSupplier無引數,回傳一個int型別結果,
IntToDoubleFunction接受一個int型別輸入,回傳一個double型別結果 ,
IntToLongFunction接受一個int型別輸入,回傳一個long型別結果,
IntUnaryOperator接受一個引數同為型別int,回傳值型別也為int ,
LongBinaryOperator接受兩個引數同為型別long,回傳值型別也為long,
LongConsumer接受一個long型別的輸入引數,無回傳值,
LongFunction< R >接受一個long型別輸入引數,回傳一個結果,
LongPredicateR接受一個long輸入引數,回傳一個布林值型別結果,
LongSupplier無引數,回傳一個結果long型別的值,
LongToDoubleFunction接受一個long型別輸入,回傳一個double型別結果,
LongToIntFunction接受一個long型別輸入,回傳一個int型別結果,
LongUnaryOperator接受一個引數同為型別long,回傳值型別也為long,
ObjDoubleConsumer< T >接受一個object型別和一個double型別的輸入引數,無回傳值,
ObjIntConsumer< T >接受一個object型別和一個int型別的輸入引數,無回傳值,
ObjLongConsumer< T >接受一個object型別和一個long型別的輸入引數,無回傳值,
Predicate< T >接受一個輸入引數,回傳一個布林值結果,
Supplier< T >無引數,回傳一個結果,
ToDoubleBiFunction<T,U>接受兩個輸入引數,回傳一個double型別結果
ToDoubleFunction< T >接受一個輸入引數,回傳一個double型別結果
ToIntBiFunction<T,U>接受兩個輸入引數,回傳一個int型別結果,
ToIntFunction< T >接受一個輸入引數,回傳一個int型別結果,
ToLongBiFunction<T,U>接受兩個輸入引數,回傳一個long型別結果,
ToLongFunction< T >接受一個輸入引數,回傳一個long型別結果,
UnaryOperator< T >接受一個引數為型別T,回傳值型別也為T,

案例(再此只演示極個別常用的,小伙伴們私底下可以自行練習):

  • consumer即消費介面,傳入一個引數,并對其進行相應的操作
public class LambdaTest {

    public void happyTime(double money,Consumer<Double> consumer){
        consumer.accept(money);
    }

    @Test
    public void test(){
        //原寫法
       happyTime(500, new Consumer<Double>() {
           @Override
           public void accept(Double aDouble) {
               System.out.println("原寫法,價格為:"+aDouble);
           }
       });

        //Lambda運算式寫法
        happyTime(500,money-> System.out.println("Lambda運算式寫法,價格為:"+money));
    }
}

在這里插入圖片描述

  • supplier即供給介面,可以傳入資料,作為一個容器;
public class LambdaTest {

    @Test
    public void test(){
        //原寫法
        Supplier<String> supplier=new Supplier<String>() {
            @Override
            public String get() {
                return "原寫法,供給型介面";
            }
        };
        System.out.println(supplier.get());

        //Lambda運算式寫法
        Supplier<String> lSupplier=()->"lambda寫法,供給型介面";
        System.out.println(lSupplier.get());
    }

}

在這里插入圖片描述

  • function即方法介面,主要是用作資料型別之間的轉換;
public class LambdaTest {

    @Test
    public void test(){
        //原寫法(給一個int 轉成字串并回傳)
        Function<Integer,String> function=new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return String.valueOf(integer);
            }
        };
        System.out.println(function.apply(10).getClass().getName());

        //Lambda運算式寫法
        Function<Integer,String> lFunction=(integer) -> String.valueOf(integer);
        System.out.println(lFunction.apply(20).getClass().getName());
    }

}

在這里插入圖片描述

  • predicate即判斷介面,傳入引數,而后回傳判斷的結果true/false;
public class LambdaTest {

    //根據給定的規則,過濾集合中的字串,此規則由Predicate的方法決定
    public List<String> filterString(List<String> list, Predicate<String> predicate){
        List<String> filterList=new ArrayList<>();
        for (String s:list){
            if (predicate.test(s)){
                filterList.add(s);
            }
        }
        return filterList;
    }

    @Test
    public void test(){
        //原寫法
        List<String> list=Arrays.asList(new String[]{"上海", "香港", "澳門", "曹縣"});
        List<String> filterString = filterString(list, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return "曹縣".equals(s) ? true : false;
            }
        });
        System.out.println(filterString);


        //Lambda運算式寫法
        List<String> lfilterString = filterString(list, s -> "上海".equals(s) ? true : false);
        System.out.println(lfilterString);
    }
}

在這里插入圖片描述


三.方法參考與構造器參考

方法參考

當要傳遞給Lambda體的操作,已經有實作的方法了,可以使用方法參考 ! 方法參考可以看作是Lambda運算式深層次的表達,換句話說,方法參考就是Lambda運算式,也就是函式式介面的一個實體,通過方法名字來指向一個方法,可以認為是Lambda運算式的一個語法糖,

語法:

使用運算子 “::” 將類(或物件)與方法名分割開來,

要求:實作介面的抽象方法的引數和回傳值型別,必須與方法參考的方法的引數串列和回傳值型別保持一致!

案例:

  1. 格式:物件 : : 非靜態方法
    @Test
    public void test(){
        //Lambda運算式寫法
        Consumer<String> consumer = str ->System.out.println(str);
        consumer.accept("Lambda運算式");

        //方法參考寫法
        Consumer<String> fConsumer = System.out::println;
        fConsumer.accept("方法參考");
    }

在這里插入圖片描述

  1. 格式:類 : : 靜態方法
public class LambdaTest {

    @Test
    public void test(){
        //Lambda運算式寫法 比較兩個數大小
        Comparator<Integer> comparator =(t1,t2) -> Integer.compare(t1,t2);
        System.out.println(comparator.compare(10,20));

        //方法參考寫法
        Comparator<Integer> fComparator = Integer::compare;
        System.out.println(fComparator.compare(20,10));
    }

}

在這里插入圖片描述

  1. 格式:類 : : 非靜態方法
    在這里插入圖片描述
    在這里插入圖片描述
public class LambdaTest {

    @Test
    public void test(){
        //Lambda運算式寫法
       Comparator<String> comparator=(s1,s2) -> s1.compareTo(s2);
       System.out.println(comparator.compare("abc","abd"));

        //方法參考寫法
        Comparator<String> fComparator = String::compareTo;
        System.out.println(fComparator.compare("www","www"));
    }

}

在這里插入圖片描述

正常來說comparator.compare("abc","abd")有兩個引數,而s1.compareTo(s2)只有一個引數并不滿足上述所說的方法參考的要求,但是為什么能用呢?因為這種情況下,第一個引數作為方法的呼叫者出現((s1,s2) -> s1.compareTo(s2)),這種情況下也存在方法參考,只不過這時候我們不是拿具體的物件寫,而是拿它的類寫(Comparator<String> fComparator = String::compareTo;)

構造器參考

呼叫的構造器會根據實作的函式介面的抽象方法的引數串列來確定,如果抽象方法為無參的,則呼叫的構造器也是無參的,

語法:

	ClassName :: new

案例

public class Student {

	public Student() {
		System.out.println("Student 無參構造已執行");
	}

	public Student(Integer id) {
		System.out.println("Student 有參構造,一個引數.為:"+id);
	}

	public Student(Integer id, String name, char sex) {
		this.id = id;
		this.name = name;
		this.sex = sex;
	}

	private Integer id;

	private String name;

	private char sex;



	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public char getsex() {
		return sex;
	}

	public void setsex(char sex) {
		this.sex = sex;
	}


	@Override
	public String toString() {
		return "Student{" +
				"id=" + id +
				", name='" + name + '\'' +
				", sex=" + sex +
				'}';
	}
}
  1. 通過無參構造器參考(創建物件)
public class LambdaTest {

	@Test
	public void test(){
		//原始寫法
		Supplier<Student> supplier =new Supplier<Student>() {
			@Override
			public Student get() {
				return new Student();
			}
		};
		supplier.get();

		//lambda運算式寫法
		Supplier<Student> lSupplier =()-> new Student();
		lSupplier.get();

		//構造器參考寫法
		Supplier<Student> gSupplier = Student::new;
		gSupplier.get();
	}

}

在這里插入圖片描述

  1. 通過有參構造器參考(一個引數,創建物件)
	@Test
	public void test(){
		//原始寫法
		Function<Integer,Student> function =new Function<Integer, Student>() {
			@Override
			public Student apply(Integer integer) {
				return new Student(integer);
			}
		};
		function.apply(1);

		//lambda運算式寫法
		Function<Integer,Student> lFunction = id -> new Student(id);
		lFunction.apply(2);

		//構造器參考寫法
		Function<Integer,Student> gFunction = Student::new;
		gFunction.apply(3);

	}

在這里插入圖片描述

陣列參考

大家可以把陣列看做是一個特殊的類,寫法與構造器參考一致,

public class LambdaTest {

	@Test
	public void test(){
		//原始寫法
		Function<Integer,String[]> function =new Function<Integer, String[]>() {
			@Override
			public String[] apply(Integer integer) {
				return new String[integer];
			}
		};
		System.out.println(Arrays.toString(function.apply(10)));

		//lambda運算式寫法
		Function<Integer,String[]> lFunction= length -> new String[length];
		System.out.println(Arrays.toString(lFunction.apply(20)));

		//構造器參考寫法
		Function<Integer,String[]> gFunction = String[] :: new;
		System.out.println(Arrays.toString(gFunction.apply(30)));
	}

}

在這里插入圖片描述


四.Stream API

Java8中有兩大最為重要的改變,第一個是Lambda運算式;另外一個則是Stream API
Stream API(java.util.Stream) 把真正的函式式編程風格引入到Java中,這是目前為止對Java類別庫最好的補充,因為Stream API 可以極大提供Java程式員的生產力,讓程式員寫出高效率,干凈,簡潔的代碼,

(Stream 使用一種類似用 SQL 陳述句從資料庫查詢資料的直觀方式來提供一種對 Java 集合運算和表達的高階抽象,)

Strema到底是什么呢?

是資料渠道,用于操作資料源(集合,陣列等) 所生成的元素序列,
“集合將的是資料,Stream講的是計算!”

語法

集合或陣列.stream().過濾().映射().終止操作

Stream 操作的三個步驟

  1. 創建 Stream
    一個資料源(集合,陣列),獲取一個流
  2. 中間操作
    一個中間操作鏈,對資料源的資料進行處理
  3. 終止操作(終端操作)
    一旦執行終止操作,就執行中間操作鏈,并產生結果,之后,不會再被使用
<style>#mermaid-svg-8pLghYUGT1rUbUma .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-8pLghYUGT1rUbUma .label text{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .node rect,#mermaid-svg-8pLghYUGT1rUbUma .node circle,#mermaid-svg-8pLghYUGT1rUbUma .node ellipse,#mermaid-svg-8pLghYUGT1rUbUma .node polygon,#mermaid-svg-8pLghYUGT1rUbUma .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-8pLghYUGT1rUbUma .node .label{text-align:center;fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .node.clickable{cursor:pointer}#mermaid-svg-8pLghYUGT1rUbUma .arrowheadPath{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-8pLghYUGT1rUbUma .flowchart-link{stroke:#333;fill:none}#mermaid-svg-8pLghYUGT1rUbUma .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-8pLghYUGT1rUbUma .edgeLabel rect{opacity:0.9}#mermaid-svg-8pLghYUGT1rUbUma .edgeLabel span{color:#333}#mermaid-svg-8pLghYUGT1rUbUma .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-8pLghYUGT1rUbUma .cluster text{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-8pLghYUGT1rUbUma .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-8pLghYUGT1rUbUma text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-8pLghYUGT1rUbUma .actor-line{stroke:grey}#mermaid-svg-8pLghYUGT1rUbUma .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-8pLghYUGT1rUbUma .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-8pLghYUGT1rUbUma #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-8pLghYUGT1rUbUma .sequenceNumber{fill:#fff}#mermaid-svg-8pLghYUGT1rUbUma #sequencenumber{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma #crosshead path{fill:#333;stroke:#333}#mermaid-svg-8pLghYUGT1rUbUma .messageText{fill:#333;stroke:#333}#mermaid-svg-8pLghYUGT1rUbUma .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-8pLghYUGT1rUbUma .labelText,#mermaid-svg-8pLghYUGT1rUbUma .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-8pLghYUGT1rUbUma .loopText,#mermaid-svg-8pLghYUGT1rUbUma .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-8pLghYUGT1rUbUma .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-8pLghYUGT1rUbUma .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-8pLghYUGT1rUbUma .noteText,#mermaid-svg-8pLghYUGT1rUbUma .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-8pLghYUGT1rUbUma .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-8pLghYUGT1rUbUma .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-8pLghYUGT1rUbUma .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-8pLghYUGT1rUbUma .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .section{stroke:none;opacity:0.2}#mermaid-svg-8pLghYUGT1rUbUma .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-8pLghYUGT1rUbUma .section2{fill:#fff400}#mermaid-svg-8pLghYUGT1rUbUma .section1,#mermaid-svg-8pLghYUGT1rUbUma .section3{fill:#fff;opacity:0.2}#mermaid-svg-8pLghYUGT1rUbUma .sectionTitle0{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .sectionTitle1{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .sectionTitle2{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .sectionTitle3{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-8pLghYUGT1rUbUma .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .grid path{stroke-width:0}#mermaid-svg-8pLghYUGT1rUbUma .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-8pLghYUGT1rUbUma .task{stroke-width:2}#mermaid-svg-8pLghYUGT1rUbUma .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .taskText:not([font-size]){font-size:11px}#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-8pLghYUGT1rUbUma .task.clickable{cursor:pointer}#mermaid-svg-8pLghYUGT1rUbUma .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-8pLghYUGT1rUbUma .taskText0,#mermaid-svg-8pLghYUGT1rUbUma .taskText1,#mermaid-svg-8pLghYUGT1rUbUma .taskText2,#mermaid-svg-8pLghYUGT1rUbUma .taskText3{fill:#fff}#mermaid-svg-8pLghYUGT1rUbUma .task0,#mermaid-svg-8pLghYUGT1rUbUma .task1,#mermaid-svg-8pLghYUGT1rUbUma .task2,#mermaid-svg-8pLghYUGT1rUbUma .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutside0,#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutside2{fill:#000}#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutside1,#mermaid-svg-8pLghYUGT1rUbUma .taskTextOutside3{fill:#000}#mermaid-svg-8pLghYUGT1rUbUma .active0,#mermaid-svg-8pLghYUGT1rUbUma .active1,#mermaid-svg-8pLghYUGT1rUbUma .active2,#mermaid-svg-8pLghYUGT1rUbUma .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-8pLghYUGT1rUbUma .activeText0,#mermaid-svg-8pLghYUGT1rUbUma .activeText1,#mermaid-svg-8pLghYUGT1rUbUma .activeText2,#mermaid-svg-8pLghYUGT1rUbUma .activeText3{fill:#000 !important}#mermaid-svg-8pLghYUGT1rUbUma .done0,#mermaid-svg-8pLghYUGT1rUbUma .done1,#mermaid-svg-8pLghYUGT1rUbUma .done2,#mermaid-svg-8pLghYUGT1rUbUma .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-8pLghYUGT1rUbUma .doneText0,#mermaid-svg-8pLghYUGT1rUbUma .doneText1,#mermaid-svg-8pLghYUGT1rUbUma .doneText2,#mermaid-svg-8pLghYUGT1rUbUma .doneText3{fill:#000 !important}#mermaid-svg-8pLghYUGT1rUbUma .crit0,#mermaid-svg-8pLghYUGT1rUbUma .crit1,#mermaid-svg-8pLghYUGT1rUbUma .crit2,#mermaid-svg-8pLghYUGT1rUbUma .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-8pLghYUGT1rUbUma .activeCrit0,#mermaid-svg-8pLghYUGT1rUbUma .activeCrit1,#mermaid-svg-8pLghYUGT1rUbUma .activeCrit2,#mermaid-svg-8pLghYUGT1rUbUma .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-8pLghYUGT1rUbUma .doneCrit0,#mermaid-svg-8pLghYUGT1rUbUma .doneCrit1,#mermaid-svg-8pLghYUGT1rUbUma .doneCrit2,#mermaid-svg-8pLghYUGT1rUbUma .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-8pLghYUGT1rUbUma .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-8pLghYUGT1rUbUma .milestoneText{font-style:italic}#mermaid-svg-8pLghYUGT1rUbUma .doneCritText0,#mermaid-svg-8pLghYUGT1rUbUma .doneCritText1,#mermaid-svg-8pLghYUGT1rUbUma .doneCritText2,#mermaid-svg-8pLghYUGT1rUbUma .doneCritText3{fill:#000 !important}#mermaid-svg-8pLghYUGT1rUbUma .activeCritText0,#mermaid-svg-8pLghYUGT1rUbUma .activeCritText1,#mermaid-svg-8pLghYUGT1rUbUma .activeCritText2,#mermaid-svg-8pLghYUGT1rUbUma .activeCritText3{fill:#000 !important}#mermaid-svg-8pLghYUGT1rUbUma .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-8pLghYUGT1rUbUma g.classGroup text .title{font-weight:bolder}#mermaid-svg-8pLghYUGT1rUbUma g.clickable{cursor:pointer}#mermaid-svg-8pLghYUGT1rUbUma g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-8pLghYUGT1rUbUma g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-8pLghYUGT1rUbUma .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-8pLghYUGT1rUbUma .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-8pLghYUGT1rUbUma .dashed-line{stroke-dasharray:3}#mermaid-svg-8pLghYUGT1rUbUma #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma .commit-id,#mermaid-svg-8pLghYUGT1rUbUma .commit-msg,#mermaid-svg-8pLghYUGT1rUbUma .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-8pLghYUGT1rUbUma g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-8pLghYUGT1rUbUma g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-8pLghYUGT1rUbUma g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-8pLghYUGT1rUbUma .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-8pLghYUGT1rUbUma .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-8pLghYUGT1rUbUma .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-8pLghYUGT1rUbUma .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-8pLghYUGT1rUbUma .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-8pLghYUGT1rUbUma .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-8pLghYUGT1rUbUma .edgeLabel text{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-8pLghYUGT1rUbUma .node circle.state-start{fill:black;stroke:black}#mermaid-svg-8pLghYUGT1rUbUma .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-8pLghYUGT1rUbUma #statediagram-barbEnd{fill:#9370db}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-state .divider{stroke:#9370db}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-8pLghYUGT1rUbUma .note-edge{stroke-dasharray:5}#mermaid-svg-8pLghYUGT1rUbUma .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-8pLghYUGT1rUbUma .error-icon{fill:#522}#mermaid-svg-8pLghYUGT1rUbUma .error-text{fill:#522;stroke:#522}#mermaid-svg-8pLghYUGT1rUbUma .edge-thickness-normal{stroke-width:2px}#mermaid-svg-8pLghYUGT1rUbUma .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-8pLghYUGT1rUbUma .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-8pLghYUGT1rUbUma .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-8pLghYUGT1rUbUma .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-8pLghYUGT1rUbUma .marker{fill:#333}#mermaid-svg-8pLghYUGT1rUbUma .marker.cross{stroke:#333} :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style> <style>#mermaid-svg-8pLghYUGT1rUbUma { color: rgba(0, 0, 0, 0.75); font: ; }</style>
資料源
filter
map
...
終止操作

注意:

  1. Stream 自已不會存盤元素
  2. Stream 不會改變源物件,相反,他們會回傳一個持有結果的新Stream
  3. Stream 操作是延遲執行的,這意味著他們會等到需要結果的時候才執行,

案例(圍繞以上三點進行操作)

首先我們先來了解兩個概念
并行流(parallelStream):多個執行緒同時運行
順序流(stream):使用主執行緒,單執行緒

  • Stream 實體化

創建 Stream 方式一:通過集合創建

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students= StudentData.getStudent();

		//回傳一個順序流
		Stream<Student> stream = students.stream();

		//回傳一個并行流
		Stream<Student> parallelStream = students.parallelStream();

	}

}

創建 Stream 方式二:通過陣列創建(Java8中的Arrays的靜態方法 Stream()可以獲取陣列流)

public class LambdaTest {

	@Test
	public void test(){
		int[] arr =new int[]{1,2,3,4,5};
		//通過泛型識明你的型別 放進去的是一個int型別的陣列,回傳的也是int型別的流
		IntStream stream = Arrays.stream(arr);
	}
}

創建 Stream 方式三:通過Stream的of()

public class LambdaTest {

	@Test
	public void test(){
		Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
	}
}

創建 Stream方式四:創建無限流 (了解)

public class LambdaTest {

	@Test
	public void test(){
		
		/**
		 * 例子:遍歷前10個偶數并列印出來
		 * iterate(): 迭代
		 * seed:種子
		 * UnaryOperator:函式式介面
		 * 注意:無限流不加對應的中間操作會無限的進行迭代 limit(10):前10個
		 */
		Stream.iterate(0, t -> t+2).limit(10).forEach(System.out::println);
	}
}
  • Stream 中間操作

多個中間操作可以連接起來形成一個 “流水線” ,除非流水線上觸發終止操作,否則中間操作不會執行任何的處理!而在終止操作時一次全部處理,成為 “惰性求值”,

篩選與切片方法描述
filter(Predicate p)接收Lambda,從流中排除某些元素
distinct()篩選,通過流所產生元素的 hashCode() 和 equals() 去除重復元素
limit(long maxSize)截斷流,使其元素不超過給定數量
skip(long n)跳過元素,回傳一個扔掉了前 n 個元素的流,若流中元素不足 n 個,則回傳一個空流,與 limit(n) 互補
映射方法描述
map(Funcation f)接收一個函式作為引數,該函式會被應用到每個元素上,并將其映射成一個新的元素
mapToDouble(ToDoubleFunction f)接收一個函式作為引數,該函式會被應用到每個元素上,產生一個新的 DoubleStream
mapToInt(TolintFunction f)接收一個函式作為引數,該函式會被應用到每個元素上,產生一個新的IntStream
mapToLong(ToLongFunction f)接收一個函式作為引數,該函式會被應用到每個元素上,產生一個新的LongStream
flatMap(Function f)接收一個函式作為引數,將流中的每個值都換成另一個流,然后把所有流連接成一個流
排序方法描述
sorted()產生一個新流,其中按自然順序排序
sorted(Comparator com)產生一個新流,其中按比較器順序排序

filter 用法

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students = StudentData.getStudent();
		//篩選出性別為男的同學資訊
		students.stream().filter(p-> '男' == p.getsex()).forEach(System.out::println);
	}
}

在這里插入圖片描述

distinct 用法 (去重復資料是通過流所生成元素的 hashCode()equals() 所以物體類中需要生成對應的方法)

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students = StudentData.getStudent();
		//去掉重復的資料
		students.stream().distinct().forEach(System.out::println);
	}
}

在這里插入圖片描述

limt 用法

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students = StudentData.getStudent();
		//展示前三個同學的資訊
		students.stream().limit(3).forEach(System.out::println);
	}

}

在這里插入圖片描述

skip 用法

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students = StudentData.getStudent();
		//顯示除了前三個之外的學生資訊
		students.stream().skip(3).forEach(System.out::println);
	}

}

在這里插入圖片描述

map 用法

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students = StudentData.getStudent();
		//獲取到男學生的姓名映射到新的集合中并列印
		students.stream().filter(student -> '男'==student.getsex()).map(Student::getName).forEach(System.out::println);
	}
}

在這里插入圖片描述

  • Stream 終止操作

終止操作 (終端操作) 從流水線生成結果,其結果可以是任何不是流的值,例如:List,Integer,甚至是 void,
流進行了終止操作后,不能再使用!

匹配與查找方法描述
allMatch(Predicate p)檢查是否匹配所有元素
anyMatch(Predicate p)檢查是否至少匹配一個元素
noneMatch(Predicate p)檢查是否沒有匹配所有元素
findFirst()回傳第一個元素
findAny()回傳當前流中的任意元素
count()回傳流中元素的總個數
max(Comparator c)回傳流中最大值
min(Comparator c)回傳流中最小值
forEach(Consumer c)內部迭代
規約 方法描述
reduce(T iden,BlnaryOperator b)可以將流中元素反復結合起來,得到一個值,回傳 T
reduce(BlnaryOperator b)可以將流中元素反復結合起來,得到一個值,回傳 Optional < T >
收集 方法描述
collect(Collector c)將流轉換為其他形式,接收一個 Collector介面的實作,用于給Stream中元素做匯總的方法

allMatch 方法 (allMatch方法需要所有匹配才會回傳true)

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students = StudentData.getStudent();
		//所有學生是不是都是男生
		boolean rst = students.stream().allMatch(student -> '男' == student.getsex());
		System.out.println(rst);
	}
}

在這里插入圖片描述

anyMatch 方法 (anyMatch方法只需要一個元素匹配就可以回傳true)

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students = StudentData.getStudent();
		//是否存在人妖
		boolean rst = students.stream().anyMatch(student -> '妖' == student.getsex());
		System.out.println(rst);
	}
}

在這里插入圖片描述

reduce 方法

public class LambdaTest {

	@Test
	public void test(){
		List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
		//計算 1-10 的自然數的和
		Integer sum = list.stream().reduce(0, Integer::sum);
		System.out.println(sum);
	}

}

在這里插入圖片描述

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students=StudentData.getStudent();
		//學生id的總和
		Optional<Integer> idSum = students.stream().map(Student::getId).reduce(Integer::sum);
		System.out.println(idSum);
	}
}

在這里插入圖片描述

collect 方法 (Collector 物件也有很多可選方法)
在這里插入圖片描述

public class LambdaTest {

	@Test
	public void test(){
		List<Student> students=StudentData.getStudent();
		//查找性別為女的學生并回傳一個 list集合
		List<Student> list = students.stream().filter(student -> '女' == student.getsex()).collect(Collectors.toList());
		System.out.println(list);
	}

}

在這里插入圖片描述

在此只演示個別的方法,小伙伴們私下可自行練習 (^ - ^) !


五.Optional類

Optional<T>類可以優雅的處理空指標例外,它可以保存T的值,代表這個值存在,或者僅僅保存null,表示這個值不存在,原來用null表示一個值不存在,現在 Optional 可以更好的表達這個概念,并且可以避免空指標例外,

Optional提供了很多方法,這樣我們就不用顯式進行空值檢測,

【創建實體物件】

創建Optional類物件方法描述
of(T t)創建一個Optional實體 t 必須非空
empty()創建一個空的 Optional 實體
ofNullable(T t)t 可以為 null

通過 of() 方法創建物件,school 不能為空,為空則拋出控制值例外

public class LambdaTest {
	@Test
	public void test() {
		School school=new School();
		Optional<School> optionalSchool = Optional.of(school);
	}
}

在這里插入圖片描述

public class LambdaTest {

	@Test
	public void test() {
		School school=new School();
		school=null;
		Optional<School> optionalSchool = Optional.of(school);
	}
}

在這里插入圖片描述

通過 ofNullable(school) 創建物件,school 可以為空

public class LambdaTest {

	@Test
	public void test() {
		School school=new School();
		school=null;
		Optional<School> optionalSchool = Optional.ofNullable(school);
		System.out.println(optionalSchool);
	}
}

在這里插入圖片描述

【對容器中物件進行操作】

判斷Optional容器中是否包含物件方法描述
boolean isPresent()判斷是否包含物件
boolean ifPresent(Consumer<? super T> consumer)如果有值,就執行Consumer介面的實作代碼,并且該值會作為引數傳給它

Optional物件的 isPresent() 方法使用

public class LambdaTest {

	@Test
	public void test() {
		School school=new School();
		school=null;
		Optional<School> optionalSchool = Optional.ofNullable(school);
		System.out.println(optionalSchool.isPresent());
	}
}

在這里插入圖片描述
【獲取容器的物件】

獲取Optional容器的物件方法描述
T get()如果呼叫物件包含值,回傳該值,否則拋例外
T orElse(T other)如果有值則將其回傳,否則回傳指定的other物件
T orElseGet(Supplier<? extends T> other)如果有值將其回傳,否則回傳由Supplier介面實作提供的物件
T orElseThrow(Supplier<? extends X> exceptionSupplier)如果有值將其回傳,否則回傳由Supplier介面實作提供的例外

orElse 方法

public class OptionalTest {
    //內部類
    public class Student{

        public Student() {
        }

        public Student(Integer id, String name) {
            this.id = id;
            this.name = name;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        private Integer id;
        private String name;
    }

    @Test
    public void test(){
        String name = getStudentName(new Student(1, "小五"));
        System.out.println(name);
    }


    private String getStudentName(Student student){
        //ofNullable()可以接收student為null
        Optional<Student> optional = Optional.ofNullable(student);
        //如果當前的optional內部封裝的student不為空,則回傳內部的studetn如果為空,則回傳.orElse(new Student(1, "張三"))方法中的引數
        return optional.orElse(new Student(1, "張三")).getName();
    }
}

在這里插入圖片描述

public class OptionalTest {
    //內部類
    public class Student{

        public Student() {
        }

        public Student(Integer id, String name) {
            this.id = id;
            this.name = name;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        private Integer id;
        private String name;
    }

    @Test
    public void test(){
        String name = getStudentName(null);
        System.out.println(name);
    }


    private String getStudentName(Student student){
        //ofNullable()可以接收student為null
        Optional<Student> optional = Optional.ofNullable(student);
        //如果當前的optional內部封裝的student不為空,則回傳內部的studetn如果為空,則回傳.orElse(new Student(1, "張三"))方法中的引數
        return optional.orElse(new Student(1, "張三")).getName();
    }

}

在這里插入圖片描述

如果明確知道資料就是非空可以搭配使用:of() + get()
如果要避免空指標的話可以搭配使用:ofNullable()+orElse()


總體來說Java8大部分都是語法相關,部分方法沒有演示,看完之后一定要多練習,熟能生巧,

最后別忘了一件三連加關注!😊 在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/292487.html

標籤:java

上一篇:新手小白學JAVA_IDEA的第一個入門案例

下一篇:Python資料結構與演算法(12)---冒泡排序

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more