java8中optional和.stream().map()


使用optional的好處:是一個可以包含或不可以包含非空值的容器對象,更加友好的處理程序中的空對象

Optional<T>有方法 isPresent() 和 get() 是用來檢查其包含的對象是否為空或不是,然后返回它,如:

Optional<SomeType> someValue = someMethod();

if (someValue.isPresent()) { // check

    someValue.get().someOtherMethod(); // retrieve and call

}

 

下面這個案例涉及到Lambda表達式 方法引用,是將單詞流中第一個以"L"開始單詞取出,作為返回結果是一個Optional<String>。

使用ifPresent()

  這個案例的代碼如下:

Stream<string> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");

Optional<string> longest = names

                                .filter(name -> name.startsWith("L"))

                                .findFirst();

 

longest.ifPresent(name -> {

            String s = name.toUpperCase();

            System.out.println("The longest name is "+ s);

        });

  這里ifPresent() 是將一個Lambda表達式作為輸入,T值如果不為空將傳入這個lambda。那么這個lambda將不為空的單詞轉為大寫輸出顯示。在前面names單詞流尋找結果中,有可能找不到開始字母為L的單詞,返回為空,也可能找到不為空,這兩種情況都傳入lambda中,無需我們打開盒子自己編寫代碼來判斷,它自動幫助我們完成了,無需人工干預。

 

使用map()

  如果你想從Optional<T>中返回一個值怎么辦?使用 map(),如下:

Stream<string> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");

Optional<string> longest = names

                                .filter(name -> name.startsWith("L"))

                                .findFirst();

 

Optional<string> lNameInCaps = longest.map(String::toUpperCase);

  使用Optional<T>的map方法能夠返回另外一個Optional,如上面的 LnameInCaps,因為傳入map()的參數值也許會導致一個空值。

 

使用orElse()

  如果在T可能空時你需要一個值的話,那么可以使用 orElse(),它能在T值存在的情況下返回這個值,否則返回輸入值。

Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");

Optional<String> longest = names

                                .filter(name -> name.startsWith("Q"))

                                .findFirst();

 

 String alternate = longest.orElse("Nimrod");

 System.out.println(alternate); //prints out "Nimrod"

 

使用orElseGet()

  orElseGet() 方法類似於orElse(),但是不是直接返回輸入參數,而是調用輸入參數,返回調用的結果,這個輸入參數通常是lambda:

Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");

Optional<String> longest = names

                                .filter(name -> name.startsWith("Q"))

                                .findFirst();

 

 String alternate = longest.orElseGet(() -> {

            // perform some interesting code operation

            // then return the alternate value.

            return "Nimrod";

 });

 System.out.println(alternate);

 

使用 orElseThrow()

  orElseThrow()是在當遭遇Null時,決定拋出哪個Exception時使用:

Stream<String> names = Stream.of("Lamurudu", "Okanbi", "Oduduwa");

 Optional<String> longest = names

                                 .filter(name -> name.startsWith("Q"))

                                 .findFirst();

 

longest.orElseThrow(NoSuchElementStartingWithQException::new);

第二部分:

在Java 8中stream().map(),您可以將對象轉換為其他對象。查看以下示例:

List<String> collect = alpha.stream().map(String::toUpperCase).collect(Collectors.toList());

 

Collectors 實現了接口 Collector<T,A,R>
T: 需要進行reduce操作的元素類型
A:reduce操作的動態集合類型
R:reduce操作的結果類型

舉例
//將名字集合到list

List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
//將名字集合到TreeSet

Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
//將名字轉換為String,並連接為一個字符串

String joined = things.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
//計算員工的工資總額

int total = employees.stream()
.collect(Collectors.summingInt(Employee::getSalary)));
//根據部門將員工分組:

Map<Department, List<Employee>> byDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
//計算不同部門的員工工資總額

Map<Department, Integer> totalByDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)));
//划分及格和不及格的學生

Map<Boolean, List<Student>> passingFailing =
students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

Collectors的官方說明見:
官網文檔

如果你對Function接口不是很了解,那么在使用這些方法時會很容易出錯,下面進行簡單的介紹:

Function<T, R>

T—函數的輸入類型
R-函數的輸出類型

也就是通過這個函數,可以將一個類型轉換為另一個類型,比如下面的例子:

//定義一個function 輸入是String類型,輸出是 EventInfo 類型, EventInfo是一個類。
Function<String, EventInfo> times2 = fun -> { EventInfo a = new EventInfo(); a.setName(fun); return a;};

String[] testintStrings={"1","2","3","4"};

//將String 的Array轉換成map,調用times2函數進行轉換
Map<String,EventInfo> eventmap1=Stream.of(testintStrings).collect(Collectors.toMap(inputvalue->inputvalue, inputvalue->times2.apply(inputvalue)));

如果Collectors.toMap的轉換過程很簡單,比如輸入和輸出類型相同,則不需要另外定義Function,例如:

Map<String,String> eventmap2=Stream.of(testStrings).collect(Collectors.toMap(inputvalue->inputval


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM