日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA基础---函数式接口、Stream流

發(fā)布時間:2023/12/18 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA基础---函数式接口、Stream流 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

函數(shù)式編程

Stream流

一、函數(shù)式編程:

1、1.概念

函數(shù)式接?在Java中是指:有且僅有?個抽象?法的接?。

函數(shù)式接?,即適?于函數(shù)式編程場景的接?。?Java中的函數(shù)式編程體現(xiàn)就是Lambda,所以函數(shù)式接? 就是可以適?于Lambda使?的接?。只有確保接?中有且僅有?個抽象?法,Java中的Lambda才能順利 地進?推導(dǎo)。

1、2.格式

只要確保接?中有且僅有?個抽象?法即可:

修飾符 interface 接?名稱 {public abstract 返回值類型 ?法名稱(可選參數(shù)信息);// 其他?抽象?法內(nèi)容 }

由于接?當(dāng)中抽象?法的 public abstract 是可以省略的,所以定義?個函數(shù)式接?很簡:

public interface MyFunctionalInterface {void myMethod(); }

1、3.自定義函數(shù)式接口

對于剛剛定義好的 MyFunctionalInterface 函數(shù)式接?,典型使?場景就是作為?法的參數(shù):

public class Demo1{Private static void do(MyFunctionalInterface inter){inter.myMethod();}public static void main(String[] args){do (() -> System.out.println("----"))} }

2、常用函數(shù)接口

2、1.Supplier

java.util.function.Supplier 接?僅包含?個?參的?法: T get() 。?來獲取?個泛型參數(shù) 指定類型的對象數(shù)據(jù)。由于這是?個函數(shù)式接?,這也就意味著對應(yīng)的Lambda表達式需要“對外提供”? 個符合泛型類型的對象數(shù)據(jù)。

實例:

import java.util.function.Supplier; public class Demo1{private static String getString(Supplier<String> function){return function.get();}public static void main(String[] args){String A = "aa";String B = "bb";System.out.println(getString(() -> A + B));} }

2.2.Consumer

java.util.function.Consumer 接?則正好與Supplier接?相反,它不是?產(chǎn)?個數(shù)據(jù),?是消費 ?個數(shù)據(jù),其數(shù)據(jù)類型由泛型決定。

抽象方法:accept

Consumer 接?中包含抽象?法 void accept(T t) ,意為消費?個指定泛型的數(shù)據(jù)。基本使?如:

import java.util.function.Consumer; public class Demo1{private static void consumeString(Consumer<String> function){ function.accept("aa");}public static void main(String[] args){consumeString(s -> System.out.println(s));} }

默認方法:andThen

如果?個?法的參數(shù)和返回值全都是 Consumer 類型,那么就可以實現(xiàn)效果:消費數(shù)據(jù)的時候,?先做? 個操作,然后再做?個操作,實現(xiàn)組合。?這個?法就是 Consumer 接?中的default?法 andThen 。 要想實現(xiàn)組合,需要兩個或多個Lambda表達式即可 。

2、3.Predicate

有時候我們需要對某種類型的數(shù)據(jù)進?判斷,從?得到?個boolean值結(jié)果。這時可以 使 java.util.function.Predicate 接?。

抽象方法:test

有時候我們需要對某種類型的數(shù)據(jù)進?判斷,從?得到?個boolean值結(jié)果。這時可以 使 java.util.function.Predicate 接?。

import java.util.function.Predicate; public class Demo15PredicateTest {private static void method(Predicate<String> predicate) {boolean veryLong = predicate.test("HelloWorld");System.out.println("字符串很?嗎:" + veryLong);}public static void main(String[] args) {method(s -> s.length() > 5);} } 默認方法:2.3.2、and:既然是條件判斷,就會存在與、或、?三種常?的邏輯關(guān)系。其中將兩個 Predicate 條件使?“與”邏輯連 接起來實現(xiàn)“并且”的效果時,可以使?default?法 and 。其JDK源碼為 ```java default Predicate<T> and(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) && other.test(t); }

2.3.3、or:

與 and 的“與”類似,默認?法 or 實現(xiàn)邏輯關(guān)系中的“或”。JDK源碼為:

default Predicate<T> or(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) || other.test(t); }

2.3.4、negate:

“與”、“或”已經(jīng)了解了,剩下的“?”(取反)也會簡單。默認?法 negate 的JDK源代碼為:

default Predicate<T> negate() {return (t) -> !test(t); }

ps:它是執(zhí)?了test?法之后,對結(jié)果boolean值進?“!”取反?已。?定要在 test ?法 調(diào)?之前調(diào)? negate ?法,正如 and 和 or ?法?樣:

2、4.Function:

java.util.function.Function 接??來根據(jù)?個類型的數(shù)據(jù)得到另?個類型的數(shù)據(jù),前者稱為 前置條件,后者稱為后置條件。

抽象?法:apply

Function 接?中最主要的抽象?法為: R apply(T t) ,根據(jù)類型T的參數(shù)獲取類型R的結(jié)果。 使?的場景例如:將 String 類型轉(zhuǎn)換為 Integer 類型。

import java.util.function.Function; public class Demo11FunctionApply {private static void method(Function<String, Integer> function) {int num = function.apply("10");System.out.println(num + 20);}public static void main(String[] args) {method(s -> Integer.parseInt(s));} }

默認方法: andThen

Function 接?中有?個默認的 andThen ?法,?來進?組合操作。JDK源代碼如:

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t)); }

ps: 該?法同樣?于“先做什么,再做什么”的場景,和 Consumer 中的 andThen 差不多

二、Stream流

1.1獲取流的方法

java.util.stream.Stream 是Java 8新加?的最常?的流接?。(這并不是?個函數(shù)式接?。) 獲取?個流?常簡單,有以下?種常?的?式:

所有的 Collection 集合都可以通過 stream 默認?法獲取流;

Stream 接?的靜態(tài)?法 of 可以獲取數(shù)組對應(yīng)的流。

import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Stream;public class Demo1 {public static void main(String[] args) {//獲得Stream對象//List獲得stream對象List <String> list = List.of("鄙人","張麻子","黃四郎");//快速生成集合,創(chuàng)建之后不可變Stream<String> stream = list.stream();//set獲得stream對象Set<String > set = Set.of("鄙人","張麻子","黃四郎");Stream<String> stream1 = set.stream();//Map獲得stream對象Map<String ,Integer>map = Map.of("鄙人",1,"張麻子",2,"黃四郎",3);Stream<String> stream2 = map.keySet().stream();Stream<Integer> stream3 = map.values().stream();Stream<Map.Entry<String, Integer>> stream4 = map.entrySet().stream();//數(shù)組獲得stream對象String [] strArr = {"鄙人","張麻子","黃四郎"};Stream<String> stream6 = Arrays.stream(strArr);Stream<Integer> stream5 = Stream.of(1,2,3,4,5);} }

1、2.常用方法:

1.2.1:逐一處理:forEach

雖然?法名字叫 forEach ,但是與for循環(huán)中的“for-each”昵稱不同。

void forEach(Consumer<? super T> action);

該?法接收?個 Consumer 接?函數(shù),會將每?個流元素交給該函數(shù)進?處理。

實例:

import java.util.stream.Stream; public class Demo12StreamForEach {public static void main(String[] args) {Stream<String> stream = Stream.of("鄙人", "張麻子", "黃老爺");stream.forEach(name-> System.out.println(name));} }

1.2.2:過濾:filter

可以通過 filter ?法將?個流轉(zhuǎn)換成另?個?集流。?法簽名:

Stream<T> filter(Predicate<? super T> predicate);

該接?接收?個 Predicate 函數(shù)式接?參數(shù)(可以是?個Lambda或?法引?)作為篩選條件。

該?法將會產(chǎn)??個boolean值結(jié)果,代表指定的條件是否滿?。如果結(jié)果為true,那么Stream流的 filter ?法將會留?元素;如果結(jié)果為false,那么 filter ?法將會舍棄元素。

實例: 通過Lambda表達式來指定了篩選的條件:必須姓張。

import java.util.stream.Stream; public class Demo07StreamFilter {public static void main(String[] args) {Stream<String> original = Stream.of("張麻子", "黃四郎", "九筒");Stream<String> result = original.filter(s -> s.startsWith("張"));} }

1.2.3:映射:map

如果需要將流中的元素映射到另?個流中,可以使? map ?法。?法簽名:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

該接?需要?個 Function 函數(shù)式接?參數(shù),可以將當(dāng)前流中的T類型數(shù)據(jù)轉(zhuǎn)換為另?種R類型的流。

實例: map ?法的參數(shù)通過?法引?,將字符串類型轉(zhuǎn)換成為了int類型(并?動裝箱為 Integer類對象)。

import java.util.stream.Stream; public class Demo08StreamMap {public static void main(String[] args) {Stream<String> original = Stream.of("10", "12", "18");Stream<Integer> result = original.map(str->Integer.parseInt(str));} }

1.2.4:統(tǒng)計個數(shù):count

正如舊集合 Collection 當(dāng)中的 size ?法?樣,流提供 count ?法來數(shù)?數(shù)其中的元素個數(shù):

long count();

該?法返回?個long值代表元素個數(shù)(不再像舊集合那樣是int值)。

import java.util.stream.Stream; public class Demo09StreamCount {public static void main(String[] args) {Stream<String> original = Stream.of("鄙人","張麻子","黃四郎");Stream<String> result = original.filter(s -> s.startsWith("張"));System.out.println(result.count()); // 2} }

1.2.5: 取?前?個:limit

limit ?法可以對流進?截取,只取?前n個。?法簽名:

Stream<T> limit(long maxSize);

參數(shù)是?個long型,如果集合當(dāng)前?度?于參數(shù)則進?截取;否則不進?操作。基本使?:

import java.util.stream.Stream; public class Demo10StreamLimit {public static void main(String[] args) {Stream<String> original = Stream.of("鄙人","張麻子","黃四郎");Stream<String> result = original.limit(2);System.out.println(result.count()); // 2} }

1.2.6: 跳過前?個:skip

如果希望跳過前?個元素,可以使? skip ?法獲取?個截取之后的新流:

Stream<T> skip(long n);

如果流的當(dāng)前?度?于n,則跳過前n個;否則將會得到?個?度為0的空流。基本使?:

import java.util.stream.Stream; public class Demo11StreamSkip {public static void main(String[] args) {Stream<String> original = Stream.of("鄙人","張麻子","黃四郎");Stream<String> result = original.skip(2);System.out.println(result.count()); // 1} }

1.2.7: 組合:concat

如果有兩個流,希望合并成為?個流,那么可以使? Stream 接?的靜態(tài)?法 concat :

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 實例: import java.util.stream.Stream; public class Demo12StreamConcat {public static void main(String[] args) {Stream<String> streamA = Stream.of("張麻子");Stream<String> streamB = Stream.of("張起靈");Stream<String> result = Stream.concat(streamA, streamB);} }

1、3 小結(jié)練習(xí)

題? :現(xiàn)在有兩個 ArrayList 集合存儲隊伍當(dāng)中的多個成員姓名,要求使?傳統(tǒng)的for循環(huán)(或增強for循環(huán))依 次進?以下若?操作步驟:

第?個隊伍只要名字為3個字的成員姓名;存儲到?個新集合中。

第?個隊伍篩選之后只要前3個?;存儲到?個新集合中。

第?個隊伍只要姓張的成員姓名;存儲到?個新集合中。

第?個隊伍篩選之后不要前2個?;存儲到?個新集合中。

將兩個隊伍合并為?個隊伍;存儲到?個新集合中。

根據(jù)姓名創(chuàng)建 Person 對象;存儲到?個新集合中。

打印整個隊伍的Person對象信息。

package Stream;import java.util.ArrayList; import java.util.stream.Stream;public class Demo4 {public static void main(String[] args) {//第??隊伍ArrayList<String> one = new ArrayList<>();one.add("迪麗熱巴");one.add("宋遠橋");one.add("蘇星河");one.add("?破天");one.add("?中?");one.add("??");one.add("莊?");one.add("洪七公");//第??隊伍ArrayList<String> two = new ArrayList<>();two.add("古?娜扎");two.add("張?忌");two.add("趙麗穎");two.add("張三豐");two.add("尼古拉斯趙四");two.add("張?zhí)鞇?#34;);two.add("張?狗");Stream<String> s1 = one.stream().filter(t -> t.length() == 3).limit(3);Stream<String> s2 = two.stream().filter(t -> t.startsWith("張")).skip(2);Stream<String> stream = Stream.concat(s1, s2);stream.map(name -> new Person(name)).forEach(p -> System.out.println(p ));} }

總結(jié)

以上是生活随笔為你收集整理的JAVA基础---函数式接口、Stream流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。