1. 程式人生 > >Java8使用小結

Java8使用小結

Oracle公司於2014年3月18日釋出了Java8,它提供了更多的程式設計工具和概念,能以更快,更重要的是能以更簡潔、更易於維護的方式解決新的或現有的程式設計問題。
本文主要整理了其中流處理、Lambda表示式、Optional類的概念與使用方式,期望有助於提供開發效率、減少程式碼複雜性。

流處理

流是一系列<u>資料項</u>,一次只生成一項。程式可以從輸入流中一個一個讀取資料項,然後以同樣的方式將資料項寫入輸出流。一個程式的輸出流很可能是另一個程式的輸入流。

一個常見的例子是Unix系統中的管道操作。一個命令的輸出可以通過管道做為另一個命令的輸入。通過簡短的命令可以實現複雜的功能。

如以下短短一行命令,就實現了讀取檔案、轉換小寫字母、按字典排序、取最後三個字母這一串處理邏輯。

cat file1 file2 | tr "[A-Z]"  "[a-z]"  |  sort  |  tail -3`

管道操作.png

構造

流有以下幾種常見的構造方式:

Stream stream=Stream.of("H","E","L","L","O");

String [] strArray=new String[]{"H","E","L","L","O"};
stream=Stream.of(strArray);
stream=Arrays.stream(strArray);

List<String> list=Arrays.asList(strArray);
stream=list.stream();

操作

中間操作:map 、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
終端操作:forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

例項

map

map操作可以改變物件的內容或型別,生成一個一對一的對映,每個輸入元素,都按照規則轉換成為另外一個元素。比如把大寫字母轉換成小寫。

Java7

List<String> wordList=Arrays.asList("H","E","L","L","O");
List<String> outputList=new ArrayList<String>();
for(String word:wordList){
    outputList.add(word.toLowerCase());
}

Java8

List<String> wordList=Arrays.asList("H","E","L","L","O");
List<String> outputList=wordList.stream().map(String::toLowerCase).collect(Collectors.toList());

flatmap

flatmap則提供一種一對多關係的對映。

List<String> hiList = Arrays.asList("hello", "hi", "你好");
List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
hiList.stream().flatMap(hi -> nameList.stream().map(name -> hi + " " + name)).collect(Collectors.toList()).forEach(System.out::println);

filter

filter對原始 Stream 進行某項測試,通過測試的元素被留下來生成一個新 Stream。

Java7

Integer[] nums={0,1,2,3,4,5,6,7,8,9};
List<Integer> oddNums=new ArrayList<Integer>(); 
for(Integer num:nums){
    if((num&1)==1){
        oddNums.add(num);
    }
}

Java8

Integer[] nums={0,1,2,3,4,5,6,7,8,9};
List<Integer> oddNums= Stream.of(nums).filter(n->(n&1)==1).collect(Collectors.toList());

foreach

forEach 方法接收一個 Lambda 表示式,然後在 Stream 的每一個元素上執行該表示式。

Java7

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
for(String name:nameList){
    System.out.println(name);
}

Java8

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.stream().forEach(System.out::println);

max

max找出最大的數。

Java7

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
Integer maxLen=Integer.MIN_VALUE;
for(String name:nameList){
    if(maxLen.compareTo(name.length())<0){
        maxLen=name.length();
    }
}

Java8

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.stream().mapToInt(String::length).max();

Lambda表示式

Lambda表示式可以理解為簡潔地表示可傳遞的匿名函式的一種方式:它沒有名稱,但它有引數列表、函式主體、返回型別,可能還有一個可以丟擲的異常列表。

  • 函式。Lambda函式不像方法那樣屬於某個特定的類。但和方法一樣,有引數列表、函式主體、返回型別,可能還有一個可以丟擲的異常列表。

  • 傳遞。Lambda表示式可以作為引數傳遞給方法或儲存在變數中。

  • 簡潔。無需像匿名類那樣寫很多模板程式碼。

Lambda結構.png

在函式式介面上都可以使用Lambda表示式。

函式式介面即只定義一個抽象方法的介面。

public interface Comparator<T>{
     int compare(T o1,T o2);
}

例項

Java7

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.sort(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
});

Java8

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.sort((String o1,String o2)->o1.compareTo(o2));

Optional類

Optional 類主要解決的問題是臭名昭著的空指標異常(NullPointerException)。

本質上,Optional是一個包含有可選值的包裝類,這意味著 Optional 類既可以含有物件也可以為空。

構造

宣告一個空的optional

Optional<Car> optCar=Optional.empty();

依據一個非空值建立Optional

Optional<Car> optCar=Optional.of(car);

可接受null的Optional

Optional<Car> optCar=Optional.ofNullable(car);

方法

get()

如果變數存在,它直接返回封裝的變數值,否則就丟擲一個NoSuchElementException異常。

orElse(T other)

它允許你在 Optional物件不包含值時提供一個預設值。

orElseGet(Supplier<? extends T> other)

它允許你在 Optional物件不包含值時執行預設方法並返回對應值。

orElseThrow(Supplier<? extends X> exceptionSupplier)

它允許你在 Optional物件不包含值時丟擲指定異常

ifPresent(Consumer<? super T>)

在變數值存在時執行一個作為引數傳入的方法,否則就不進行任何操作。

例項

Java7

public static String getName(User u) {
    if (u == null)
        return "Unknown";
    return u.name;
}

Java8

public static String getName(User u) {
    return Optional.ofNullable(u)
                    .map(user->user.name)
                    .orElse("Unknown");
}


歡迎Java工程師朋友們加入Java工程師學習交流群:795632998

本群提供免費的學習指導 架構資料 以及解答

不懂得問題都可以在本群提出來 之後還會有職業生涯規劃以及面試指導