Java8 學(xué)習(xí)總結(jié)

Lambda 表達(dá)式

Lambda 是一個(gè)匿名函數(shù),我們可以把 Lambda 表達(dá)式理解為是一段可以傳遞的代碼(將代碼像數(shù)據(jù)一樣進(jìn)行傳遞)剩檀』劭猓可以寫出更簡(jiǎn)潔、更靈活的代碼。作為一種更緊湊的代碼風(fēng)格麸俘,使Java的語(yǔ)言表達(dá)能力得到了提升辩稽。

Lambda 表達(dá)式在Java 語(yǔ)言中引入了一個(gè)新的語(yǔ)法元素和操作符。這個(gè)操作符為 “->” 从媚, 該操作符被稱為 Lambda 操作符或箭頭操作符搂誉。它將 Lambda 分為兩個(gè)部分:

- 左側(cè):指定了 Lambda 表達(dá)式需要的所有參數(shù)

- 右側(cè):指定了 Lambda 體,即 Lambda 表達(dá)式要執(zhí)行的功能静檬。

Lambda 表達(dá)式語(yǔ)法

語(yǔ)法格式一:無(wú)參炭懊,無(wú)返回值,Lambda 體只需一條語(yǔ)句

Runnable runnable = () -> System.out.println("hello Lambda");

語(yǔ)法格式二:Lambda 需要一個(gè)參數(shù)

Consumer<String> con = (t) -> System.out.println(t);

語(yǔ)法格式三:Lambda 只需要一個(gè)參數(shù)時(shí)拂檩,參數(shù)的小括號(hào)可以省略

Consumer<String> con = t -> System.out.println(t);

語(yǔ)法格式四:Lambda 需要兩個(gè)參數(shù)侮腹,并且有返回值

Comparator<Integer> comparator = (x,y) -> {

? ? ? ? System.out.println("相加結(jié)果是:"+(x+y));

? ? ? ? return Integer.compare(x,y);

? ? };

語(yǔ)法格式五:當(dāng) Lambda 體只有一條語(yǔ)句時(shí),return 與大括號(hào)可以省略

Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);

語(yǔ)法格式六:數(shù)據(jù)類型可以省略稻励,因?yàn)榭捎删幾g器推斷得出父阻,稱為“類型推斷”

Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);

類型判斷

Lambda 表達(dá)式中無(wú)需指定類型,程序依然可以編譯望抽,這是因?yàn)?javac 根據(jù)程序的上下文加矛,在后臺(tái)推斷出了參數(shù)的類型。Lambda 表達(dá)式的類型依賴于上下文環(huán)境煤篙,是由編譯器推斷出來(lái)的斟览。這就是所謂的“類型推斷”。

函數(shù)式接口

只包含一個(gè)抽象方法的接口辑奈,稱為函數(shù)式接口苛茂。

可以通過(guò) Lambda 表達(dá)式來(lái)創(chuàng)建該接口的對(duì)象。(若 Lambda 表達(dá)式拋出一個(gè)受檢異常鸠窗,那么該異常需要在目標(biāo)接口的抽象方法上進(jìn)行聲明)妓羊。

我們可以在任意函數(shù)式接口上使用 @FunctionalInterface 注解,這樣做可以檢查它是否是一個(gè)函數(shù)式接口稍计,同時(shí) javadoc 也會(huì)包含一條聲明躁绸,說(shuō)明這個(gè)接口是一個(gè)函數(shù)式接口。

Java 內(nèi)置四大核心函數(shù)式接口

方法引用

當(dāng)要傳遞給Lambda體的操作臣嚣,已經(jīng)有實(shí)現(xiàn)的方法了净刮,可以使用方法引用(實(shí)現(xiàn)抽象方法的參數(shù)列表,必須與方法引用方法的參數(shù)列表保持一致茧球。)方法引用:使用操作符 “::” 將方法名和對(duì)象或類的名字分隔開來(lái)庭瑰。

如下三種主要使用情況:

- 對(duì)象::實(shí)例方法

- 類::靜態(tài)方法

- 類::實(shí)例方法

使用注意事項(xiàng):

* 1.Lambda 體中調(diào)用方法的參數(shù)列表與返回值類型,要與函數(shù)式接口中抽象方法的函數(shù)列表和返回值類型保持一致星持。

* 2.若Lambda 參數(shù)列表中第一個(gè)參數(shù)是實(shí)例方法調(diào)用者,第二個(gè)參數(shù)是實(shí)例方法的參數(shù) 可以使用 ClassName :: method

構(gòu)造器引用

與函數(shù)式接口相結(jié)合抢埋,自動(dòng)與函數(shù)式接口中方法兼容。可以把構(gòu)造器引用賦值給定義的方法揪垄,與構(gòu)造器參數(shù)列表要與接口中抽象方法的參數(shù)列表一致穷吮!

格式: ClassName::new

數(shù)組引用

格式: type[] :: new

? ? /**

? ? * 方法引用:若Lambda 體中的內(nèi)容有方法已經(jīng)實(shí)現(xiàn)了,可以使用"方法引用"

? ? */

? ? public class TestMethodRef {

? ? ? ? @Test

? ? ? ? public void test1(){

? ? ? ? ? ? Consumer<String> con = (x) -> System.out.println(x);

? ? ? ? ? ? con.accept("shuai");

? ? ? ? ? ? //方法引用,對(duì)象::實(shí)例方法名

? ? ? ? ? ? Consumer<String> consumer = System.out::println;

? ? ? ? ? ? consumer.accept("test");

? ? ? ? }

? ? ? ? @Test

? ? ? ? public void test2(){

? ? ? ? ? ? Person person = new Person();

? ? ? ? ? ? Supplier<String> supplier = () -> person.getName();

? ? ? ? ? ? String str = supplier.get();

? ? ? ? ? ? System.err.println(str);

? ? ? ? ? ? //方法引用,對(duì)象::實(shí)例方法名

? ? ? ? ? ? Supplier<Integer> sup = person::getAge;

? ? ? ? ? ? Integer age = sup.get();

? ? ? ? ? ? System.out.println(age);

? ? ? ? }

? ? ? ? //類::靜態(tài)方法名

? ? ? ? @Test

? ? ? ? public void test3(){

? ? ? ? ? ? Comparator<Integer> com = (x,y) -> Integer.compare(x, y);

? ? ? ? ? ? //使用前提,compare的參數(shù)和返回值與Comparator一致

? ? ? ? ? ? Comparator<Integer> comparator = Integer :: compare;

? ? ? ? }

? ? ? ? //類::實(shí)例方法名

? ? ? ? @Test

? ? ? ? public void test4(){

? ? ? ? ? ? BiPredicate<String, String> bp = (x,y) -> x.equals(y);

? ? ? ? ? ? //使用條件:第一個(gè)參數(shù)是實(shí)例方法調(diào)用者,第二個(gè)參數(shù)是實(shí)例方法的參數(shù)

? ? ? ? ? ? BiPredicate<String, String> biPredicate = String :: equals;

? ? ? ? }

? ? ? ? //構(gòu)造器引用

? ? ? ? @Test

? ? ? ? public void test5(){

? ? ? ? ? ? Supplier<Person> sup = () -> new Person();

? ? ? ? ? ? //構(gòu)造器引用方式

? ? ? ? ? ? Supplier<Person> supplier = Person :: new;

? ? ? ? ? ? Person person = supplier.get();

? ? ? ? ? ? System.out.println(person);

? ? ? ? }

? ? ? ? //構(gòu)造器引用

? ? ? ? @Test

? ? ? ? public void test6(){

? ? ? ? ? ? Function<Integer, Person> fun = (x) -> new Person(x);

? ? ? ? ? ? Function<Integer, Person> function = Person :: new;

? ? ? ? ? ? Person person = function.apply(2);

? ? ? ? ? ? System.out.println(person);

? ? ? ? ? ? System.out.println("--------------------");

? ? ? ? ? ? BiFunction<String, Integer, Person> biFunction = Person :: new;

? ? ? ? ? ? Person person2 = biFunction.apply("張三", 23);

? ? ? ? ? ? System.out.println(person2);

? ? ? ? }

? ? ? ? //數(shù)組引用

? ? ? ? @Test

? ? ? ? public void test7(){

? ? ? ? ? ? Function<Integer, String[]> fun = (x) -> new String[x];

? ? ? ? ? ? String[] strs = fun.apply(8);

? ? ? ? ? ? System.out.println(strs.length);

? ? ? ? ? ? Function<Integer, String[]> function = String[] :: new;

? ? ? ? ? ? String[] strArray = function.apply(6);

? ? ? ? ? ? System.out.println(strArray.length);

? ? ? ? }

? ? }

Stream API

Stream 是 Java8 中處理集合的關(guān)鍵抽象概念饥努,它可以指定 希望對(duì)集合進(jìn)行的操作捡鱼,可以執(zhí)行非常復(fù)雜的查找、過(guò)濾和映射數(shù)據(jù)等操作酷愧。使用Stream API 對(duì)集合數(shù)據(jù)進(jìn)行操作驾诈,就類似于使用 SQL 執(zhí)行的數(shù)據(jù)庫(kù)查詢。也可以使用 Stream API 來(lái)并行執(zhí)行操作溶浴。簡(jiǎn)而言之乍迄,Stream API 提供了一種高效且易于使用的處理數(shù)據(jù)的方式。

Stream

是數(shù)據(jù)渠道士败,用于操作數(shù)據(jù)源(集合闯两、數(shù)組等)所生成的元素序列。

“集合講的是數(shù)據(jù)谅将,流講的是計(jì)算漾狼!”

1. Stream 自己不會(huì)存儲(chǔ)元素。

2. Stream 不會(huì)改變?cè)磳?duì)象饥臂。相反逊躁,他們會(huì)返回一個(gè)持有結(jié)果的新Stream。

3. Stream 操作是延遲執(zhí)行的隅熙。這意味著他們會(huì)等到需要結(jié)果的時(shí)候才執(zhí)行志衣。

Stream 的操作三個(gè)步驟

創(chuàng)建 Stream

一個(gè)數(shù)據(jù)源(如:集合、數(shù)組)猛们,獲取一個(gè)流

中間操作

一個(gè)中間操作鏈念脯,對(duì)數(shù)據(jù)源的數(shù)據(jù)進(jìn)行處理

終止操作(終端操作)

一個(gè)終止操作,執(zhí)行中間操作鏈弯淘,并產(chǎn)生結(jié)果

創(chuàng)建Stream?

Java8 中的 Collection 接口被擴(kuò)展绿店,提供了兩個(gè)獲取流的方法:

- default Stream stream() : 返回一個(gè)順序流

- default Stream parallelStream() : 返回一個(gè)并行流

Java8 中的 Arrays 的靜態(tài)方法 stream() 可以獲取數(shù)組流:

- static Stream stream(T[] array): 返回一個(gè)流

可以使用靜態(tài)方法 Stream.of(), 通過(guò)顯示值創(chuàng)建一個(gè)流。它可以接收任意數(shù)量的參數(shù)庐橙。

- public static Stream of(T… values) : 返回一個(gè)流

可以使用靜態(tài)方法 Stream.iterate() 和Stream.generate(), 創(chuàng)建無(wú)限流假勿。

- 迭代

public static Stream iterate(final T seed, final UnaryOperator f)

- 生成

public static Stream generate(Supplier s) :

? ? //創(chuàng)建Stream

? ? @Test

? ? public void test1(){

? ? ? ? //1.可以通過(guò)Collection系列集合提供的stream() 或parallelStream()

? ? ? ? List<String> list = new ArrayList<>();

? ? ? ? Stream<String> stream = list.stream();

? ? ? ? //2.通過(guò)Arrays中靜態(tài)方法 stream() 獲取數(shù)組流

? ? ? ? Person[] persons = new Person[10];

? ? ? ? Stream<Person> stream2 = Arrays.stream(persons);

? ? ? ? //3.通過(guò)Stream類中的靜態(tài)方法 of()

? ? ? ? Stream<String> stream3 = Stream.of("a","b","c");

? ? ? ? //4.創(chuàng)建無(wú)限流

? ? ? ? //迭代

? ? ? ? Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);

? ? ? ? stream4.limit(8).forEach(System.out :: println);

? ? ? ? //生成

? ? ? ? Stream.generate(() -> Math.random()).limit(6)

? ? ? ? ? ? .forEach(System.out :: println);

? ? }? ? ?

Stream 的中間操作

多個(gè)中間操作可以連接起來(lái)形成一個(gè)流水線,除非流水線上觸發(fā)終止操作态鳖,否則中間操作不會(huì)執(zhí)行任何的處理转培!而在終止操作時(shí)一次性全部處理,稱為“惰性求值”浆竭。

? ? /**

? ? * Stream API的中間操作

? ? */

? ? public class TestSteamAPI2 {

? ? ? ? List<Person> persons = Arrays.asList(

? ? ? ? ? ? ? ? new Person(2, "錢四", 24),

? ? ? ? ? ? ? ? new Person(1, "張三", 33),

? ? ? ? ? ? ? ? new Person(2, "李四", 24),

? ? ? ? ? ? ? ? new Person(3, "王五", 65),

? ? ? ? ? ? ? ? new Person(4, "趙六", 26),

? ? ? ? ? ? ? ? new Person(5, "陳七", 27)

? ? ? ? );

? ? ? ? //內(nèi)部迭代浸须,由Stream API完成

? ? ? ? @Test

? ? ? ? public void test1(){

? ? ? ? ? ? //中間操作,不會(huì)執(zhí)行任何操作

? ? ? ? ? ? Stream<Person> stream = persons.stream()

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .filter((e) -> {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("Stream的中間操作");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return e.getAge() > 25;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? //終止操作惨寿,一次性執(zhí)行全部?jī)?nèi)容,即"惰性求值"

? ? ? ? ? ? stream.forEach(System.out :: println);

? ? ? ? }

? ? ? ? //外部迭代

? ? ? ? @Test

? ? ? ? public void test2(){

? ? ? ? ? ? Iterator<Person> iterator = persons.iterator();

? ? ? ? ? ? while (iterator.hasNext()) {

? ? ? ? ? ? ? ? System.out.println(iterator.next());

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //limit删窒,截?cái)?/p>

? ? ? ? @Test

? ? ? ? public void test3(){

? ? ? ? ? ? persons.stream()

? ? ? ? ? ? ? ? .filter((e) -> {

? ? ? ? ? ? ? ? ? ? System.out.println("迭代操作"); //短路

? ? ? ? ? ? ? ? ? ? return e.getAge() > 24;

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .limit(2)

? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? }

? ? ? ? //跳過(guò)skip,distinct去重(要重寫equals和hashcode)

? ? ? ? @Test

? ? ? ? public void test4(){

? ? ? ? ? ? persons.stream()

? ? ? ? ? ? ? ? ? ? .filter((e) -> e.getAge() > 23)

? ? ? ? ? ? ? ? ? ? .skip(2)

? ? ? ? ? ? ? ? ? ? .distinct()

? ? ? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? }

? ? ? ? //映射

? ? ? ? @Test

? ? ? ? public void test5(){

? ? ? ? ? ? List<String> list = Arrays.asList("a","bb","c","d","e");

? ? ? ? ? ? list.stream().map((str) -> str.toUpperCase())

? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? ? ? System.out.println("---------------");

? ? ? ? ? ? persons.stream().map((Person :: getName)).forEach(System.out :: println);

? ? ? ? ? ? System.out.println("---------------");

? ? ? ? ? ? Stream<Stream<Character>> stream = list.stream()

? ? ? ? ? ? ? ? .map(TestSteamAPI2 :: filterCharacter);

? ? ? ? ? ? stream.forEach((s) -> {

? ? ? ? ? ? ? ? s.forEach(System.out :: println);

? ? ? ? ? ? });

? ? ? ? ? ? System.out.println("-----------------");

? ? ? ? ? ? //flatMap

? ? ? ? ? ? Stream<Character> stream2 = list.stream()

? ? ? ? ? ? ? ? .flatMap(TestSteamAPI2 :: filterCharacter);

? ? ? ? ? ? stream2.forEach(System.out :: println);

? ? ? ? }

? ? ? ? //處理字符串

? ? ? ? public static Stream<Character> filterCharacter(String str){

? ? ? ? ? ? List<Character> list = new ArrayList<>();

? ? ? ? ? ? for (Character character : str.toCharArray()) {

? ? ? ? ? ? ? ? list.add(character);

? ? ? ? ? ? }

? ? ? ? ? ? return list.stream();

? ? ? ? }

? ? ? ? //排序

? ? ? ? @Test

? ? ? ? public void test6(){

? ? ? ? ? ? List<String> list = Arrays.asList("bb","c","aa","ee","ddd");

? ? ? ? ? ? list.stream()

? ? ? ? ? ? ? ? .sorted() //自然排序

? ? ? ? ? ? ? ? .forEach(System.out :: println);

? ? ? ? ? ? System.out.println("------------");

? ? ? ? ? ? persons.stream()

? ? ? ? ? ? ? ? ? ? .sorted((p1,p2) -> {

? ? ? ? ? ? ? ? ? ? ? ? if (p1.getAge() == p2.getAge()) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? return p1.getName().compareTo(p2.getName());

? ? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? return p1.getAge() - p2.getAge();

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }).forEach(System.out :: println);

? ? ? ? }

? ? }

接口中的默認(rèn)方法與靜態(tài)方法

接口中的默認(rèn)方法

Java 8中允許接口中包含具有具體實(shí)現(xiàn)的方法裂垦,該方法稱為“默認(rèn)方法”,默認(rèn)方法使用 default 關(guān)鍵字修飾肌索。

接口默認(rèn)方法的”類優(yōu)先”原則

若一個(gè)接口中定義了一個(gè)默認(rèn)方法蕉拢,而另外一個(gè)父類或接口中又定義了一個(gè)同名的方法時(shí)

- 選擇父類中的方法。如果一個(gè)父類提供了具體的實(shí)現(xiàn)诚亚,那么接口中具有相同名稱和參數(shù)的默認(rèn)方法會(huì)被忽略晕换。

- 接口沖突。如果一個(gè)父接口提供一個(gè)默認(rèn)方法站宗,而另一個(gè)接口也提供了一個(gè)具有相同名稱和參數(shù)列表的方法(不管方法是否是默認(rèn)方法)届巩,那么必須覆蓋該方法來(lái)解決沖突。

接口中的靜態(tài)方法

Java8 中份乒,接口中允許添加靜態(tài)方法恕汇。

? ? public interface MyInterface {

? ? ? ? default String getName(){

? ? ? ? ? ? return "接口測(cè)試";

? ? ? ? }

? ? ? ? public static void show(){

? ? ? ? ? ? System.out.println("接口中的靜態(tài)方法");

? ? ? ? }

? ? }

新特性:

? ? public static void main(String[] args) throws InterruptedException, ExecutionException {

? ? ? ? DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");

? ? ? ? Callable<LocalDate> callable = new Callable<LocalDate>() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public LocalDate call() throws Exception {

? ? ? ? ? ? ? ? return LocalDate.parse("20170521",dtf);

? ? ? ? ? ? }

? ? ? ? };

? ? ? ? ExecutorService pool = Executors.newFixedThreadPool(10);

? ? ? ? List<Future<LocalDate>> results = new ArrayList<>();

? ? ? ? for (int i = 0; i < 8; i++) {

? ? ? ? ? ? results.add(pool.submit(callable));

? ? ? ? }

? ? ? ? for (Future<LocalDate> future : results) {

? ? ? ? ? ? System.out.println(future.get());

? ? ? ? }

? ? ? ? //關(guān)閉資源

? ? ? ? pool.shutdown();

}

LocalDate LocalTime LocalDateTime

? ? //1.LocalDate LocalTime LocalDateTime

? ? @Test

? ? public void test1(){

? ? ? ? LocalDateTime ldt = LocalDateTime.now();

? ? ? ? System.out.println(ldt);

? ? ? ? LocalDateTime ldt2 = LocalDateTime.of(2017, 05, 21, 21, 43, 55, 33);

? ? ? ? System.out.println(ldt2);

? ? ? ? LocalDateTime ldt3 = ldt.plusYears(3);

? ? ? ? System.out.println(ldt3);

? ? ? ? LocalDateTime ldt4 = ldt.minusMonths(5);

? ? ? ? System.out.println(ldt4);

? ? }

解析與格式化

java.time.format.DateTimeFormatter 類

該類提供了三種格式化方法:

- 預(yù)定義的標(biāo)準(zhǔn)格式

- 語(yǔ)言環(huán)境相關(guān)的格式

- 自定義的格式

? ? //DateTimeFormatter:格式化時(shí)間/日期

? ? @Test

? ? public void test6(){

? ? ? ? DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;

? ? ? ? LocalDateTime ldt = LocalDateTime.now();

? ? ? ? System.out.println(ldt);

? ? ? ? String format = ldt.format(dtf);

? ? ? ? System.out.println(format);

? ? ? ? System.out.println("------------");

? ? ? ? DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");

? ? ? ? String format2 = dtf2.format(ldt);

? ? ? ? System.out.println(format2);

? ? ? ? LocalDateTime ldt2 = ldt.parse(format2,dtf2);

? ? ? ? System.out.println(ldt2);

? ? }

HashMap

HashMap:減少碰撞,位置相同時(shí),條件達(dá)到鏈表上超過(guò)8個(gè),總數(shù)超過(guò)64個(gè)時(shí),數(shù)據(jù)結(jié)構(gòu)改為紅黑樹。

ConcurrentHashMap:取消鎖分段或辖,與HashMap相同瘾英,達(dá)到條件時(shí),數(shù)據(jù)結(jié)構(gòu)改為紅黑樹颂暇。

Optional 類

Optional 類(java.util.Optional) 是一個(gè)容器類缺谴,代表一個(gè)值存在或不存在,原來(lái)用 null 表示一個(gè)值不存在耳鸯,現(xiàn)在 Optional 可以更好的表達(dá)這個(gè)概念湿蛔。并且可以避免空指針異常。

常用方法:

- Optional.of(T t) : 創(chuàng)建一個(gè) Optional 實(shí)例

- Optional.empty() : 創(chuàng)建一個(gè)空的 Optional 實(shí)例

- Optional.ofNullable(T t):若 t 不為 null,創(chuàng)建 Optional 實(shí)例,否則創(chuàng)建空實(shí)例

- isPresent() : 判斷是否包含值

- orElse(T t) : 如果調(diào)用對(duì)象包含值县爬,返回該值阳啥,否則返回t

- orElseGet(Supplier s) :如果調(diào)用對(duì)象包含值,返回該值财喳,否則返回 s 獲取的值

- map(Function f): 如果有值對(duì)其處理察迟,并返回處理后的Optional,否則返回 Optional.empty()

- flatMap(Function mapper):與 map 類似耳高,要求返回值必須是Optional

? ? /**

? ? * Optional類

? ? */

? ? public class TestOptional {

? ? ? ? @Test

? ? ? ? public void test1(){

? ? ? ? ? ? //參數(shù)不能為空

? ? ? ? ? ? Optional<Person> op = Optional.of(new Person());

? ? ? ? ? ? Person person = op.get();

? ? ? ? ? ? System.out.println(person);

? ? ? ? }

? ? ? ? @Test

? ? ? ? public void test2(){

? ? ? ? ? ? //構(gòu)建空optional

? ? ? ? ? ? Optional<Person> op = Optional.empty();

? ? ? ? ? ? System.out.println(op.get());

? ? ? ? }

? ? ? ? @Test

? ? ? ? public void test3(){

? ? ? ? ? ? //如果為null扎瓶,調(diào)用empty,如果不為null泌枪,調(diào)用of

? ? ? ? ? ? Optional<Person> op = Optional.ofNullable(null);

? ? //? ? ? Optional<Person> op = Optional.ofNullable(new Person());

? ? ? ? ? ? if (op.isPresent()) {

? ? ? ? ? ? ? ? System.out.println(op.get());

? ? ? ? ? ? }

? ? ? ? ? ? //有值就用值概荷,沒(méi)值就替代

? ? ? ? ? ? Person person = op.orElse(new Person("張三", 23));

? ? ? ? ? ? System.out.println(person);

? ? ? ? }

? ? }

重復(fù)注解與類型注解

Java 8對(duì)注解處理提供了兩點(diǎn)改進(jìn):可重復(fù)的注解及可用于類型的注解。

? ? @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

? ? @Retention(RetentionPolicy.RUNTIME)

? ? public @interface MyAnnotations {

? ? ? ? MyAnnotation[] value();

? ? }

? ? @Repeatable(MyAnnotations.class)

? ? @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ElementType.TYPE_PARAMETER})

? ? @Retention(RetentionPolicy.RUNTIME)

? ? public @interface MyAnnotation {

? ? ? ? String value() default "aric";

? ? }

? ? /**

? ? * 重復(fù)注解與類型注解

? ? */

? ? public class TestAnnotation {

? ? ? ? @MyAnnotation("hello")

? ? ? ? @MyAnnotation("test")

? ? ? ? public void show(@MyAnnotation("a") String str){

? ? ? ? ? ? System.out.println(str);

? ? ? ? }

? ? }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碌燕,一起剝皮案震驚了整個(gè)濱河市误证,隨后出現(xiàn)的幾起案子继薛,更是在濱河造成了極大的恐慌,老刑警劉巖雷厂,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異叠殷,居然都是意外死亡改鲫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門林束,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)像棘,“玉大人,你說(shuō)我怎么就攤上這事壶冒÷铺猓” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵胖腾,是天一觀的道長(zhǎng)烟零。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咸作,這世上最難降的妖魔是什么锨阿? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮记罚,結(jié)果婚禮上墅诡,老公的妹妹穿的比我還像新娘。我一直安慰自己桐智,他們只是感情好末早,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著说庭,像睡著了一般然磷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刊驴,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天样屠,我揣著相機(jī)與錄音,去河邊找鬼缺脉。 笑死痪欲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的攻礼。 我是一名探鬼主播业踢,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼礁扮!你這毒婦竟也來(lái)了知举?” 一聲冷哼從身側(cè)響起瞬沦,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雇锡,沒(méi)想到半個(gè)月后逛钻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锰提,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年曙痘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片立肘。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡边坤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谅年,到底是詐尸還是另有隱情茧痒,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布融蹂,位于F島的核電站旺订,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏超燃。R本人自食惡果不足惜耸峭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淋纲。 院中可真熱鬧劳闹,春花似錦、人聲如沸洽瞬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)伙窃。三九已至菩颖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間为障,已是汗流浹背晦闰。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳍怨,地道東北人呻右。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鞋喇,于是被迫代替她去往敵國(guó)和親声滥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 點(diǎn)贊+收藏 就學(xué)會(huì)系列侦香,文章收錄在 GitHub JavaEgg 落塑,N線互聯(lián)網(wǎng)開發(fā)必備技能兵器譜 Java8早在2...
    JavaKeeper_海星閱讀 320評(píng)論 0 0
  • 1. 為什么要用流纽疟? 先看下流處理有什么優(yōu)勢(shì)吧:下面兩段代碼都是用來(lái)返回低熱量的菜肴名稱的,并按照卡路里排序憾赁,一個(gè)...
    little田同學(xué)閱讀 564評(píng)論 0 1
  • java8新特性 原創(chuàng)者:文思 一污朽、特性簡(jiǎn)介 速度更快 代碼更少,增加了Lambda 強(qiáng)大的Stream API ...
    文思li閱讀 3,050評(píng)論 1 1
  • 0龙考、java新特性簡(jiǎn)介 速度更快數(shù)據(jù)結(jié)構(gòu)發(fā)生變化jvm內(nèi)存模型變化 新生代蟆肆、老年代、永久區(qū)洲愤、方法計(jì)數(shù)器颓芭、棧新的垃圾...
    liangflying閱讀 459評(píng)論 0 1
  • JAVA 8 新特性 Java 8 應(yīng)該是目前項(xiàng)目中使用最多的版本顷锰,之前有使用過(guò)它的一些新特性柬赐,了解一些基本的用法...
    caoshenyang閱讀 632評(píng)論 0 2