一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java中的函數式編程

Java中的函數式編程

2022-02-21 14:26sofia Java教程

這篇文章介紹Java中的函數式編程,函數式編程是一種編程范式,其中程序是通過應用和組合函數來構造的。它是一種聲明式編程范式,其中函數定義是表達式樹,每個表達式樹返回一個值,而不是一系列改變程序狀態的命令語句,

函數式編程是一種編程范式,其中程序是通過應用和組合函數來構造的。它是一種聲明式編程范式,其中函數定義是表達式樹,每個表達式樹返回一個值,而不是一系列改變程序狀態的命令語句

Java8引入了Lambda形式的函數式編程。術語Lambda來自Lambda演算,用于描述計算。

1、Lambda

我們可以將lambda表達式視為一個匿名函數,可以將其分配給變量并傳遞給方法,該方法接受函數接口作為參數。Lambda表達式沒有名稱,但它有一個參數列表、一個主體和一個返回類型。

(parameters) -> expression

lambda表達式可以在函數接口的上下文中使用。

2、函數接口

函數接口是只指定一個抽象方法的接口。

?
1
2
3
4
5
6
public interface Comparator<T> {                          
    int compare(T o1, T o2);
}
public interface Runnable {                               
    void run();
}

Lambda表達式允許我們直接內聯提供函數接口的抽象方法的實現,并將整個表達式視為函數接口的實例。

2.1 函數描述符

我們將函數接口的抽象方法的簽名稱為函數描述符。函數描述符描述lambda表達式的簽名。例如,我們可以將 Runnable 的函數描述符看作 ()->void ,因為它有一個抽象方法,不接受任何內容,也不返回任何內容(void)。

3、Java函數接口

3.1 Predicate

Predicate<T> 接口定義了一個名為 test 的抽象方法,該方法接受一個泛型類型為 T 的對象并返回一個布爾值。此接口可用于表示使用T類型對象的布爾表達式。

函數描述符: T->boolean

?
1
2
3
4
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

3.2 Consumer

java.util.function.Consumer<T> 接口定義了一個名為 accept 的抽象方法,該方法接受一個泛型類型為 T 的對象,并且不返回任何結果( void )。當我們需要訪問T類型的對象并對其執行某些操作時,可以使用此接口。

函數描述符: T->void

3.3 Function

java.util.function.function<T,R> 接口定義了一個名為 apply 的抽象方法,該方法將一個泛型類型為 T 的對象作為輸入,并返回一個泛型類型為 R 的對象。當我們需要定義一個lambda將信息從輸入對象映射到輸出時,可以使用該接口。

函數描述符: T->R

3.4 Supplier

接口 java.util.function.Supplier<T> 定義了一個名為 get 的抽象方法,該方法不接受任何內容并返回類型為T的對象。

函數描述符: ()->R

3.5 Primitive Specializations

原語接口是專用接口,用于在輸入或輸出為原語時避免自動裝箱操作。

?
1
2
3
public interface IntPredicate {
    boolean test(int t);
}

4、類型檢查

lambda的類型是從使用lambda的上下文中推導出來的。上下文中lambda表達式所需的類型(例如,傳遞給它的方法參數或分配給它的局部變量)稱為目標類型。Lambda表達式可以從賦值上下文、方法調用上下文(參數和返回)和強制轉換上下文中獲取其目標類型。

?
1
Object o = (Runnable) () -> System.out.println("Hello");

4.1 Capturing Lambda

lambda可以不受限制地捕獲(在其主體中引用)實例變量和靜態變量。但是當捕獲局部變量時,它們必須顯式地聲明為 final 或實際上是 final

我們為何有這個限制?

實例變量存儲在堆上,而局部變量位于堆棧上。如果lambda可以直接訪問局部變量,并且lambda在線程中使用,那么使用lambda的線程可以在分配變量的線程解除分配變量后嘗試訪問該變量。因此,Java將對自由局部變量的訪問實現為對其副本的訪問,而不是對原始變量的訪問。如果局部變量只分配給一次,則這沒有什么區別,因此存在限制。

5、方法引用

有三種主要的方法參考:

  • 對靜態方法的方法引用。例如, – Integer::parseInt
  • 對任意類型的實例方法的方法引用。示例– String::length
  • 對現有對象或表達式的實例方法的方法引用。示例– student::getRank ,其中 student 是具有方法 getRank() student 類型的局部變量
?
1
2
List<String> list = Arrays.asList("a","b","A","B");
list.sort((s1, s2) -> s1.compareToIgnoreCase(s2));

可以寫成

?
1
2
List<String> list = Arrays.asList("a","b","A","B");
list.sort(String::compareToIgnoreCase);

5.1 構造函數引用

可以使用 ClassName::new 引用現有構造函數

?
1
Supplier<List<String>> supplier = ArrayList::new ;與 Supplier<List<String>> supplier = () -> new ArrayList<>() 相同;

5.2 組合Lambda

許多函數接口包含可用于組合lambda表達式的默認方法。組合示例-

將兩個謂詞組合成一個較大的謂詞,在兩個謂詞之間執行or操作
反向或鏈式比較器

5.3 Comparators

按逆序排列學生

?
1
2
Comparator<Student> c = Comparator.comparing(Student::getRank);
students.sort(comparing(Student::getRank).reversed());

根據姓名(反向)對學生進行排序,然后按反向順序排列

?
1
2
students.sort(comparing(Student::getName).reversed()
        .thenComparing(Student::getRank));

5.4 Predicates

Predicates接口包括三個方法: negate , and , 和 or ,可用于創建更復雜的謂詞。

?
1
2
Predicate<Integer> naturalNumber = i -> i > 0;                                    
Predicate<Integer> naturalNumberLessThanHundred = naturalNumber.and( i -> i < 100);

5.5 Functions

函數接口帶有兩個默認方法, andThen compose

Consider f(x) = x2 and g(x) = x3 + 1 then

g(f(x)) ->

?
1
2
3
4
Function<Integer,Integer> square = n -> n*n;                        
Function<Integer,Integer> squareAndCube = square.andThen(n -> n*n*n+1);
System.out.println(squareAndCube.apply(2)); 
65

f(g(x)) ->

?
1
2
3
Function<Integer,Integer> square = n -> n*n;                             
Function<Integer,Integer> squareAndCube = square.compose(n -> n*n*n + 1);
System.out.println(squareAndCube.apply(2));

應用Lambda

讓我們看看如何編寫一個通用方法來根據 veratain 屬性過濾一組書籍(將其視為sqlwhere子句)。

?
1
2
3
4
public static List<Book> filter(Predicate<Book> where) {               
  List<Book> books = Catalogue.books();                                
  return books.stream().filter(where).collect(Collectors.toList());    
}

Lambda表達式通過不同的過濾器過濾不同的書籍

?
1
2
List<Book> javaBook = filter(book -> book.getCategory().equals(JAVA));              
List<Book> joshuaBlochBook = filter(book -> book.getAuthor().equals("Joshua Bloch"));

6、總結

lambda表達式可以被認為是一個匿名函數,可以在函數接口的上下文中使用。函數接口是只指定一個抽象方法的接口。

到此這篇關于Java中的函數式編程的文章就介紹到這了,更多相關Java 函數式編程內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://javakk.com/2449.html?utm_source=tuicool&utm_medium=referral

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 图片专区亚洲欧美另类 | 天天操天天爽天天射 | 精品视频 久久久 | 高h禁伦奶水女 | 熟睡中的麻麻大白屁股小说 | 日韩一区国产二区欧美三 | 91短视频在线观看2019 | 四虎b7s22c0m| 国产大片51精品免费观看 | 亚洲小视频 | 99re免费在线视频 | 蜜柚精彩在线观看 | 日本厕所spy2wc| 亚洲免费国产 | 无套日出白浆在线播放 | 三级无删减高清在线影院 | 日韩美女强理论片 | 美女班主任下面好爽好湿好紧 | 青青在线视频免费 | 亚洲免费视频一区二区三区 | 久久精品视频91 | 陈峰姚瑶全集小说无删节 | 美女福利视频一区二区 | 美女班主任让我爽了一夜视频 | 好大好湿好硬好爽好深免费视频 | 亚洲一二三区久久五月天婷婷 | porono日本人xxx | aaaaa特级毛片 | 91免费视频国产 | 91成人爽a毛片一区二区 | 2020韩国三级理论在线观看 | 国产精品久久久久久久久99热 | 91桃花| 国产自拍视频网站 | 99热精品69堂国产 | 日韩在线视精品在亚洲 | 国产高清路线一路线二2022 | 九九热综合 | 深夜网站在线观看 | 亚洲精品国产自在现线最新 | 日本高清免费不卡在线播放 |