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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java8 的 Stream 流式操作之王者归来

發布時間:2025/3/20 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java8 的 Stream 流式操作之王者归来 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相對于Java8之前的Java的相關操作簡直是天差地別,Java8 的流式操作的出現,也很大程度上改變了開發者對于Java的繁瑣的操作的印象,從此,Java也走向了函數式編程的道路!

1 流的創建

1.1 流的創建方法

既然需要聊聊流的操作,那么,首先還是先看看怎么創建流。

創建流的方法有三種,分別是:Stream.of()、Stream.iterate()、Stream.generate(),然后,分別看一下這三個方法的聲明。

static <T> Stream<T> of(T... values)static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)static <T> Stream<T> generate(Supplier<T> s)

Stream.of():參數很簡單,就是一系列的泛型參數。
Stream.iterate():第一個參數是一個初始值,第二個參數是一個操作。
Stream.generate():參數就是一個Supplier的供給型的參數。

1.2 流的創建方法舉例

/** @Author 歐陽思海* @Description 創建流* @Date 11:05 2019/8/26* @Param []* @return void**/@Testpublic void testCreateStream() {//利用Stream.of方法創建流Stream<String> stream = Stream.of("hello", "world", "Java8");stream.forEach(System.out::println);System.out.println("##################");//利用Stream.iterate方法創建流Stream.iterate(10, n -> n 1).limit(5).collect(Collectors.toList()).forEach(System.out::println);System.out.println("##################");//利用Stream.generate方法創建流Stream.generate(Math::random).limit(5).forEach(System.out::println);System.out.println("##################");//從現有的集合中創建流List<String> strings = Arrays.asList("hello", "world", "Java8");String string = strings.stream().collect(Collectors.joining(","));System.out.println(string);}

在上面的例子中,Stream.of()方法的參數是幾個字符串,Stream.iterate()方法的第一個參數是初始值 10,第二個參數是在10 的基礎上每次加 1 的操作,Stream.generate()的參數是用 Random 方法產生隨機數。

1.3 流的創建總結

流的創建有三種方法,分別是Stream.of()、Stream.iterate()、Stream.generate(),這幾個都是 Stream 類的靜態方法,所以,使用起來非常的方便。

2 流的操作

在上一節中,我們知道怎么創建流了,接下來,我們就看看對流可以進行哪些操作,使用了 Stream 流之后,是否會比 Java8 之前方便很多呢?

2.1 裝箱流

在處理對象流的時候,可以利用 Collectors 類的靜態方法轉換為集合,例如,將字符串流轉換為 List<String> ,這種方式是沒有問題的。

但是,如果遇到 double流想要轉換為 List 時,這是就會報錯。

DoubleStream.of(1.0, 2.0, 3.0).collect(Collectors.toList());//錯誤的寫法

這種方式就是錯誤的,編譯是不能通過的。

別慌,對于這種問題,有 3 種比較好的解決方法。

利用 boxed 方法

利用 boxed 方法,可以將 DoubleStream 轉換為 Stream<Double> ,例如;

DoubleStream.of(1.0, 2.0, 3.0).boxed().collect(Collectors.toList());

這樣就解決了上面的問題。

利用 mapToObj 方法

利用 mapToObj 方法也可以實現上面的功能,另外,也提供了 mapToInt、mapToLong、mapToDouble 等方法將基本類型流轉換為相關包裝類型。

DoubleStream.of(1.0, 2.0, 3.0).mapToObj(Double::valueOf).collect(Collectors.toList());
collect 方法

一般情況下,我們利用 collect 方法的時候,都是用于將流的數據收集為基本類型的集合,例如;

stream.collect(Collectors.toList())

然而,collect 方法其實還有一種更加一般化的形式,如下;

<R> R collect(Supplier<R> supplier,ObjIntConsumer<R> accumulator,BiCnsumer<R,R> combiner)

上面這種方法的第一個參數是一個供給器,相當于初始化一個容器,第二個參數是累加器,相當于給初始化的容器賦值,第三個參數是組合器,相當于將這些元素全部組合到一個容器

下面,我們通過一個簡單的例子來看看到底是怎么使用的!

List<Double> list = DoubleStream.of(1.0, 2.0, 3.0).collect(ArrayList<Double>::new, ArrayList::add, ArrayList::addAll);

上面的例子我們可以看到,第一個參數:使用一個靜態方法初始化一個 List 容器,第二個參數:使用靜態方法 add ,添加元素,第三個參數:使用靜態方法 addAll ,用于聯合所有的元素。

從最后的返回值為 List<Double>,我們也可以看出,全部組合成一個初始化的 List 集合中了。

2.2 字符串與流之間的轉換

這一小節主要講解一下字符串與流之間的轉換,將 String 轉為流有兩種方法,分別是 java.lang.CharSequence 接口定義的默認方法 chars 和 codePoints ,而將流轉為字符串就是我們前面已經講解到的方法 collect 。

/** @Author 歐陽思海* @Description 字符串與流之間的轉換* @Date 9:41 2019/9/2* @Param []* @return void**/@Testpublic void testString2Stream() {String s = "hello world Java8".codePoints()//轉換成流.collect(StringBuffer::new,StringBuffer::appendCodePoint,StringBuffer::append)//將流轉換為字符串.toString();String s1 = "hello world Java8".chars()//轉換成流.collect(StringBuffer::new,StringBuffer::appendCodePoint,StringBuffer::append)//將流轉換為字符串.toString();}

在上面的例子中,先用chars 和 codePoints 方法轉換為流,然后都是利用 collect 方法再轉回字符串。

2.3 流的映射 map 與 flatMap

流的映射是什么意思呢,我們先將一個在 Java8 之前的例子,我們常常需要將一個集合的對象的某一個字段取出來,然后再存到另外一個集合中,這種場景我們在 Java8 之前我們會這樣實現。

/** @Author 歐陽思海* @Description Java8之前的用法* @Date 19:31 2019/9/2* @Param []* @return void**/@Testpublic void testList() {List<Person> list = new ArrayList<>();List<Friend> friends = new ArrayList<>();friends.add(new Friend("Java5"));friends.add(new Friend("Java6"));friends.add(new Friend("Java7"));Person person = new Person();person.setFriends(friends);list.add(person);List<String> strings = new ArrayList<>();for(Person p : list){strings.add(p.getName());}}

是不是這樣很麻煩,這也就是以前大家一直所說的 Python 用一招,Java 需要用花招!

但是,Java8 卻改變了這種現實,我們來看一看怎么使用 map 和 flatMap。

首先,我們先看一下這倆個方法的聲明

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

接下來,我們用這兩個方法改寫上面的方式,先看看 map 方法;

/** @Author 歐陽思海* @Description map、flatMap方法* @Date 9:50 2019/9/2* @Param []* @return void**/@Testpublic void testMapAndFlatMap() {List<Person> list = new ArrayList<>();List<Friend> friends = new ArrayList<>();friends.add(new Friend("Java5"));friends.add(new Friend("Java6"));friends.add(new Friend("Java7"));Person person = new Person();person.setFriends(friends);list.add(person);//映射出名字List<String> strings = list.stream().map(Person::getName).collect(Collectors.toList());}

通過使用 map 方法,參數給定 Person::getName 映射出 name,然后再用 collect 收集到 List 中,就完成了上面的負責的操作,是不是很舒服。

但是,如果我們用 map 方法想要映射出 friends 屬性,會遇到一個問題;

//映射出朋友List<List<Friend>> collect = list.stream().map(Person::getFriends).collect(Collectors.toList());

我們發現,上面的返回值是 List<List<Friend>>,這種形式集合里面還包著集合,處理有點麻煩,但是,不是還有另外 flatMap 沒有使用嗎,這個方法正好能夠解決這個問題。

List<Friend> collect1 = list.stream().flatMap(friend -> friend.getFriends().stream()).collect(Collectors.toList());

發現,這個方法的返回值是 List<Friend>,正如我們看到的,flatMap 的方法能夠“展平”包裹的流,這就是 map 和 flatMap 的區別。

2.4 流的連接

流的連接有兩種方式,如果是兩個流的連接,使用 Stream.concat 方法,如果是三個及三個以上的流的連接,就使用 Stream.flatMap 方法。

/*** @return void* @Author 歐陽思海* @Description 流的連接* @Date 10:13 2019/9/2* @Param []**/@Testpublic void testConcatStream() {//兩個流的連接Stream<String> first = Stream.of("sihai", "sihai2", "sihai3");Stream<String> second = Stream.of("sihai4", "sihai5", "sihai6");Stream<String> third = Stream.of("siha7", "sihai8", "sihai9");Stream<String> concat = Stream.concat(first, second);//多個流的連接Stream<String> stringStream = Stream.of(first, second, third).flatMap(Function.identity());}

3 流的規約操作

流的規約操作幾種類型,這里都講一下。

內置的規約操作

基本類型流都有內置的規約操作。包括average、count、max、min、sum、summaryStatistics,前面的幾個方法相信不用說了,summaryStatistics 方法是前面的幾個方法的結合,下面我們看看他們如何使用。

/*** @return void* @Author 歐陽思海* @Description 內置規約操作* @Date 22:04 2019/9/1* @Param []**/@Testpublic void testReduce1() {String[] strings = {"hello", "sihai", "hello", "Java8"};long count = Arrays.stream(strings).map(String::length).count();System.out.println(count);System.out.println("##################");int sum = Arrays.stream(strings).mapToInt(String::length).sum();System.out.println(sum);System.out.println("##################");OptionalDouble average = Arrays.stream(strings).mapToInt(String::length).average();System.out.println(average);System.out.println("##################");OptionalInt max = Arrays.stream(strings).mapToInt(String::length).max();System.out.println(max);System.out.println("##################");OptionalInt min = Arrays.stream(strings).mapToInt(String::length).min();System.out.println(min);DoubleSummaryStatistics statistics = DoubleStream.generate(Math::random).limit(1000).summaryStatistics();System.out.println(statistics);}

就是這么簡單!

基本的規約操作

基本的規約操作是利用前面講過的 reduce 方法實現的,IntStream 接口定義了三種 reduce 方法的重載形式,如下;

OptionalInt reduce(IntBinaryOperator op)int reduce(int identity, IntBianryOperator op)<U> U reduce(U identity,BiFunction<U,? super T,U> accumulator,BianryOperator<U> combiner)

上面的 identity 參數就是初始化值的意思,IntBianryOperator 類型的參數就是操作,例如 lambda 表達式;BianryOperator<U> combiner是一個組合器,在前面有講過。

下面我們通過一個例子來講解一下。

/*** @return void* @Author 歐陽思海* @Description reduce規約操作* @Date 22:20 2019/9/1* @Param []**/@Testpublic void testReduce2() {int sum = IntStream.range(1, 20).reduce((x, y) -> x y).orElse(0);System.out.println(sum);System.out.println("##################");int sum2 = IntStream.range(1, 20).reduce(0, (x, y) -> x 2 * y);System.out.println(sum2);System.out.println("##################");int sum3 = IntStream.range(1, 20).reduce(0, Integer::sum);System.out.println(sum3);}

例子中的第一個是1到20累加的操作,第二個以0為初始值,然后2倍累加,第三個是以0為初始值,累加

流的計數

流的數量統計有兩種方法,分別是 Stream.count() 方法和 Collectors.counting() 方法。

/*** @return void* @Author 歐陽思海* @Description 統計測試* @Date 23:29 2019/9/1* @Param []**/@Testpublic void testStatistics() {//統計數量String[] strings = {"hello", "sihai", "hello", "Java8"};long count = Arrays.stream(strings).count();System.out.println(count);System.out.println("##################");Long count2 = Arrays.stream(strings).collect(Collectors.counting());System.out.println(count2);}

4 流的查找與匹配

流的查找

流的查找 Stream 接口提供了兩個方法 findFirst 和 findAny。

findFirst 方法返回流中的第一個元素的 Optional,而 findAny 方法返回流中的某個元素的 Optional。

我們來看一個例子。

String[] strings = {"hello", "sihai", "hello", "Java8"};Optional<String> first = Arrays.stream(strings).findFirst();System.out.println(first.get());System.out.println("##################");Optional<String> any = Arrays.stream(strings).findAny();System.out.println(any.get());System.out.println("##################");

流的匹配

流的匹配 Stream 接口提供了三個方法,分別是 anyMatch(任何一個元素匹配,返回 true)、allMatch(所有元素匹配,返回 true)、noneMatch(沒有一個元素匹配,返回 true)。

boolean b = Stream.of(1, 2, 3, 4, 5, 10).anyMatch(x -> x > 5);System.out.println(b);System.out.println("##################");boolean b2 = Stream.of(1, 2, 3, 4, 5, 10).allMatch(x -> x > 5);System.out.println(b2);System.out.println("##################");boolean b3 = Stream.of(1, 2, 3, 4, 5, 10).noneMatch(x -> x > 5);System.out.println(b3);

5 流的總結

這篇文章主要講解了流的一些操作,包括下面幾個方面。

  • 流的創建方法。
  • 流的系列操作,包括裝箱流、字符串與流之間的轉換、流和映射 map 和 flatMap、流的連接。
  • 流的規約操作
  • 流的查找與匹配

文章有不當之處,歡迎指正,如果喜歡微信閱讀,你也可以關注我的微信公眾號:好好學java,獲取優質學習資源。

總結

以上是生活随笔為你收集整理的Java8 的 Stream 流式操作之王者归来的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日批在线观看 | 国产欧美日韩三区 | 一级片网址 | www好男人 | www.四虎影视.com | 激情综合丁香五月 | 在线播放无码后入内射少妇 | wwwwww色| 欧美视频免费在线 | 天堂影视av | 亚洲一区二区三 | 亚洲aaaa级特黄毛片 | 免费一级片视频 | 亚洲天堂免费在线观看视频 | 天天摸天天摸 | 99久久精品免费看国产交换 | 蜜臀久久99精品久久久画质超高清 | 成人免费毛片嘿嘿连载 | 久久精品欧美日韩 | 欧美大片aaa| 日韩欧美视频在线播放 | 不卡中文字幕在线观看 | 美女超碰在线 | 天天操一操 | 久久成年人视频 | 在线播放www | 成人性生活视频 | 夜色在线影院 | 色中色综合网 | 国产亚洲精品久 | 久久无码人妻一区二区三区 | 中文字幕一区二区视频 | 一区二区三区四区免费 | 欧美做受喷浆在线观看 | 台湾佬美性中文娱乐网 | 你懂的国产视频 | 国产日本视频 | 女人特黄大aaaaaa大片 | 超污视频在线观看 | 蜜臀一区二区三区 | 91视频啊啊啊 | 精品久久在线 | 成年人免费在线观看网站 | 淫五月| 青青青青青青草 | 免费看色 | 捆绑无遮挡打光屁股调教女仆 | 国产交换配乱淫视频免费 | 久久影院中文字幕 | 国产老女人乱淫免费可以 | 欧美伊人影院 | 亚洲一区二区三区中文字幕 | 亚洲av片一区二区三区 | 长河落日电视连续剧免费观看 | 污污视频免费观看 | 91精品国产高清一区二区三密臀 | 午夜激情在线 | 免费精品视频在线观看 | 男女日批免费视频 | 成人做爰www免费看视频网站 | 国产激情片 | 天天操天天玩 | 欧美日韩精品久久久免费观看 | 伊人网在线观看 | 成人片黄网站色大片免费毛片 | 亚洲国产精品成人综合在线 | 欧美色图久久 | 免费无遮挡无码永久视频 | 成人网免费看 | 亚洲理论在线 | 久久免费av| 神马午夜dy888 | 性欧美videos高清hd4k | 在线观看国产亚洲 | 黑人操日本 | 亚洲深夜福利 | 亚洲精品久久久久久一区二区 | 久久久久人妻一区精品 | 色七七久久 | 中日精品一色哟哟 | 乖女从小调教h尿便器小说 欧美韩一区二区 | 国产免费无码XXXXX视频 | 麻豆免费在线 | jizz黑人| 久久综合久色欧美综合狠狠 | 激情文学88| 视频免费在线 | 欧美在线小视频 | 亚洲国产视频在线观看 | 国产黄大片在线观看画质优化 | 国产一级片免费播放 | 中文字幕 人妻熟女 | 浪荡奴双性跪着伺候 | 欧美不卡影院 | 欧美精品久久99 | 成人18视频免费69 | 亚洲精品乱码久久久久久不卡 | 夜夜干天天操 | 黄网在线观看视频 |