java8Stream

来源:https://www.cnblogs.com/moyuduo/archive/2020/04/01/12616827.html
-Advertisement-
Play Games

Stream 介紹 java8添加了一個抽象流Stream,可以讓我們像寫sql一樣操作集合元素。Stream將要處理的元素看做是一種流, 在管道中傳輸,併進行處理,最後由終止操作得到處理的結果。 什麼是Stream? Stream是一個來自特定元素隊列並支持聚合操作 元素是具體類型的對象,形成一個 ...


Stream

介紹

java8添加了一個抽象流Stream,可以讓我們像寫sql一樣操作集合元素。Stream將要處理的元素看做是一種流, 在管道中傳輸,併進行處理,最後由終止操作得到處理的結果。

什麼是Stream?

Stream是一個來自特定元素隊列並支持聚合操作

  • 元素是具體類型的對象,形成一個隊列。
  • 數據源是流的來源。
  • 聚合操作是類似sql一樣的操作,比如filter, map, reduce, find, match, sorted等。
  • Stream自己不會存儲元素。
  • Stream不會改變源對象。
  • Stream操作是延遲執行的。

創建流

串列流

stream():即單線程的方式去操作流

並行流

parallelStream():即多線程方式去操作流

@Test
	public void test() {
		//1通過Collection提供的stream()和parallelStream()方法
		List<String> list = Arrays.asList("a","b","c");
		Stream<String> stream1 = list.stream();
		Stream<String> stream2 = list.parallelStream();
		
		//2通過Arrays的靜態方法stream()
		String[] strs= {"a","b","c"};
		Stream<String> stream3 = Arrays.stream(strs);
		
		//3通過Stream類中的靜態方法of()
		Stream<String> stream4 = Stream.of("a","b","c");
		
		//4通過Stream類的iterate方法生成無限流
		Stream<Integer> stream5 = Stream.iterate(0, (x)->x+1);
		
		//5通過Stream的generate方法生成無限流
		Stream.generate(()->Math.random());
		
	}

中間操作

過濾

使用 filter(Predicate<? super T> predicate)來按照一定規則對流中元素進行過濾

@Test
	public void test() {
		List<Integer> list = Arrays.asList(1,2,3,4,5);
		Stream<Integer> stream = list.stream();
		stream = stream.filter((x)->x.compareTo(2)>0);
		
		stream.forEach(System.out::println);
	}
輸出:
3
4
5

@Test
	public void test2() {
		List<Integer> list = Arrays.asList(1,2,3,4,5);
		Stream<Integer> stream = list.stream();
		stream = stream.filter(
				(x)->{
			System.out.println(x);
			return x.compareTo(2)>0;}
			);
	}
結果:沒有任何輸出,這也就是前面說的Stream操作是延遲執行的,只有當終止操作這些中間操作才會依次執行

截斷

使元素的個數不超過指定的數目

@Test
	public void test() {
		List<Integer> list = Arrays.asList(1,2,3,4,5);
		Stream<Integer> stream = list.stream();
		stream=stream.limit(3);
		stream.forEach(System.out::println);
	}
輸出:
1
2
3
可以看到只輸出了給定個元素

跳過元素

跳過流中前幾個元素

@Test
	public void test4() {
		List<Integer> list = Arrays.asList(1,2,3,4,5);
		Stream<Integer> stream = list.stream();
		stream=stream.skip(2);
		stream.forEach(System.out::println);
	}
輸出:
3
4
5
跳過了前兩個元素

唯一篩選

兩個元素通過hashCode()判斷兩個元素是否相同

@Test
	public void test5() {
		List<Integer> list = Arrays.asList(1,2,3,4,5,5);
		Stream<Integer> stream = list.stream();
		stream.distinct().forEach(System.out::println);
	}
輸出:
1
2
3
4
5

映射

map(method)接受一個方法,把流中的元素按照方法進行轉換

@Test
	public void test() {
		List<String> list = Arrays.asList("a","b","c");
		Stream<String> stream = list.stream();
		stream=stream.map((x)->x.toUpperCase());
		stream.forEach(System.out::println);
	}
輸出:
A
B
C

flatMap(method)也是接受一個函數作為參數,但是與map,不同的是如果這個函數生成的本來就是流,它會把函數生成流中的元素加到流中

//這個函數本身就生成流
public static Stream<Character> toStream(String s){
  List<Character> list=new ArrayList<Character>();
  char[] chs = s.toCharArray();
  for (char c : chs) {
    list.add(c);
  }
  Stream<Character> stream = list.stream();
  return stream;
}
@Test
public void test() {
  List<String> list = Arrays.asList("aaa","bbb","ccc");
  Stream<Stream<Character>> stream = 
  //由於函數本身就生成流,所以流中加入的還是流
  list.stream().map(StreamTest::toStream);
  //遍歷的時候需要先從流中取出流,在遍歷
  stream.forEach((s)->s.forEach(System.out::println));
}

//然而我們可以使用flatMap進行改進
@Test
public void test() {
  List<String> list = Arrays.asList("aaa","bbb","ccc");
  list.stream().flatMap(StreamTest::toStream).forEach(System.out::println);
}
輸出:
a
a
a
b
b
b
c
c
c

終止操作

所有匹配

當所有元素都匹配時,allMatch(Predicate<? super T> predicate)才會返回true

@Test
public void test() {
  List<String> list = Arrays.asList("aaa","bbb","ccc");
  boolean allMatch = list.stream().allMatch((s)->s.length()>2);
  System.out.println(allMatch);
}
輸出:
true

任一匹配

當Stream中任一一個元素匹配時,anyMatch(Predicate<? super T> predicate)返回true

@Test
public void test() {
  List<String> list = Arrays.asList("aaa","bbb","ccc");
  boolean anyMatch = list.stream().anyMatch((s)->s.equals("bbb"));
  System.out.println(anyMatch);
}
輸出:
true

所有不匹配

當Stream中所有的元素都不匹配時,noneMatch(Predicate<? super T> predicate)返回true

@Test
public void test() {
  List<String> list = Arrays.asList("aaa","bbb","ccc");
  boolean noneMatch = list.stream().noneMatch((s)->s.equals("ddd"));
  System.out.println(noneMatch);
}
輸出:
true

第一個元素

返回當前流中的第一個元素

@Test
public void test() {
  List<Integer> list = Arrays.asList(1,2,3,4,5);
  Optional<Integer> findFirst = list.stream().findFirst();
  System.out.println(findFirst.get());
}
輸出:
1

任一一個元素

返回當前流中的任一一個元素

@Test
public void test() {
  List<Integer> list = Arrays.asList(1,2,3,4,5);
  Optional<Integer> findAny = list.stream().findAny();
  System.out.println(findAny.get());
}
輸出:
1

//使用並行流試試
@Test
public void test13() {
	List<Integer> list = Arrays.asList(1,2,3,4,5);
	Optional<Integer> findAny =   		list.parallelStream().findAny();
	System.out.println(findAny.get());
}
輸出:
3

流中元素個數

返迴流中的元素個數

@Test
public void test14() {
  List<Integer> list = Arrays.asList(1,2,3,4,5);
  long count = list.stream().count();
  System.out.println(count);
}
輸出:
5

流中的最大值

返迴流中元素的最大值

@Test
public void test15() {
  List<Integer> list = Arrays.asList(1,2,3,4,5);
  Optional<Integer> max = list.stream().max(Integer::compare);
  System.out.println(max.get());
}
輸出:
5

流中的最小值

返迴流中的最小值

@Test
public void test16() {
  List<Integer> list = Arrays.asList(1,2,3,4,5);
  Optional<Integer> min = list.stream().min(Integer::compare);
  System.out.println(min.get());
}
輸出:
1

規約

將流中的元素反覆結合得到一個最終值

@Test
public void test() {
  List<Integer> list = Arrays.asList(1,2,3,4,5);
  Optional<Integer> reduce = list.stream().reduce(Integer::sum);
  System.out.println(reduce.get());

  Integer reduce2 = list.stream().reduce(0, (x,y)->{
    System.out.println(x+"->"+y);
    return x+y;
  });
  System.out.println(reduce2);
}
輸出:
15
0->1
1->2
3->3
6->4
10->5
15

可以看到當使用(T identity, BinaryOperator accumulator)時,identity即為最初和流中元素進行運算的,所以值不能為空,所以返回的不是Optional

收集

將流轉換成其他形式

@Test
public void test() {
  List<Integer> list = Arrays.asList(1,2,3,4,5,5);
  Set<Integer> collect = list.stream().collect(Collectors.toSet());
  System.out.println(collect);
}
輸出:
[1, 2, 3, 4, 5]

@Test
public void test() {
		List<Integer> list = Arrays.asList(1,2,3,4,5,5);
		Optional<Integer> collect = list.stream().collect(Collectors.maxBy(Integer::compareTo));
		System.out.println(collect.get());
}
輸出:
5

class Stu{
	String name;
	Integer age;
	String gender;
	public Stu(String name, Integer age, String gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	@Override
	public String toString() {
		return "Stu [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}
	
}
//一級分組
@Test
	public void test() {
		List<Stu> list = Arrays.asList(
				new Stu("張三",20,"男"),
				new Stu("李四",22,"女"),
				new Stu("王五",18,"男"),
				new Stu("趙六",20,"女"),
				new Stu("田七",22,"女")
				);
		Map<String, List<Stu>> collect = 				list.stream().collect(Collectors.groupingBy(Stu::getGender));
		System.out.println(collect);
	}
輸出:
{女=[Stu [name=李四, age=22, gender=女], Stu [name=趙六, age=20, gender=女], Stu [name=田七, age=22, gender=女]], 男=[Stu [name=張三, age=20, gender=男], Stu [name=王五, age=18, gender=男]]}

//二級分組
@Test
public void test21() {
  List<Stu> list = Arrays.asList(
    new Stu("張三",20,"男"),
    new Stu("李四",22,"女"),
    new Stu("王五",18,"男"),
    new Stu("趙六",20,"女"),
    new Stu("田七",22,"女")
  );
  Map<Integer, Map<String, List<Stu>>> collect = list.stream()
    .collect(Collectors.groupingBy(Stu::getAge, Collectors.groupingBy(Stu::getGender)));
  System.out.println(collect);
}
輸出:
{18={男=[Stu [name=王五, age=18, gender=男]]}, 20={女=[Stu [name=趙六, age=20, gender=女]], 男=[Stu [name=張三, age=20, gender=男]]}, 22={女=[Stu [name=李四, age=22, gender=女], Stu [name=田七, age=22, gender=女]]}}

//分區
@Test
public void test22() {
  List<Stu> list = Arrays.asList(
    new Stu("張三",20,"男"),
    new Stu("李四",22,"女"),
    new Stu("王五",18,"男"),
    new Stu("趙六",20,"女"),
    new Stu("田七",22,"女")
  );
  Map<Boolean, List<Stu>> collect = list.stream()
    .collect(Collectors.partitioningBy((e)->((Stu)e).getAge()>20));
  System.out.println(collect);
}
輸出:
{false=[Stu [name=張三, age=20, gender=男], Stu [name=王五, age=18, gender=男], Stu [name=趙六, age=20, gender=女]], true=[Stu [name=李四, age=22, gender=女], Stu [name=田七, age=22, gender=女]]}


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JavaScript 操作 DOM 時經常會用到一些尺寸,本文介紹怪異模式和標準模式下的滾動條距離、視窗尺寸、文檔尺寸、元素文檔坐標的相容性寫法以及視窗滾動到指定位置的方法 ...
  • 內容中的{{var}}會直接顯示,使用過濾器:{{var | 過濾器名}},會先用過濾器處理var,再顯示。 按作用域劃分,有2種過濾器:全局過濾器、組件內過濾器。 demo 組件內過濾器 <div id="app"> <input v-model="content" /><br /> <!--綁定 ...
  • Netty是Trustin Lee在2004年開發的一款高性能的網路應用程式框架。相比於JDK自帶的NIO,Netty做了相當多的增強,且隔離了jdk nio的實現細節,API也比較友好,還支持流量整形等高級特性。在我們常見的一些開源項目中已經普遍的應用到了Netty,比如Dubbo、Elastic ...
  • 物聯網mqtt協議是可以發佈和訂閱通過java就可以實現 話不多說,mqtt,載入pom.xml文件格式 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema- ...
  • 1. Netty 基礎 Netty 是一個高性能、非同步事件驅動的 NIO 框架,它提供了對 TCP、UDP 和文件傳輸的支持,作為一個非同步 NIO 框架,Netty 的所有 IO 操作都是非同步非阻塞的,通過 Future-Listener 機制,用戶可以方便的主動獲取或者通過通知機制獲得 IO 操作 ...
  • 在練習迴圈刪除list中元素時遇到了一點問題。最開始寫的代碼是 for i in range(len(list)): del list[i] 這樣寫到後來會報錯,原因是隨著列表元素的刪除和i的增加,對列表元素的訪問會越界。 後來改成瞭如下代碼 while i < len(list): del lis ...
  • 一、線程的優先順序 1.線程優先順序的獲取的CPU時間片會相對多一點 (1)優先順序為1-10 (2)最低為1 (3)最高為10 (4)預設為5 package com.bjpowernode.java_learning; ​ public class D105_1_PriorotyOfMultithre ...
  • 一旦被初始化就不可以被改變。 String s1 = new String("abc"); String s2 = "abc"; System.out.println(s1==s2);//false System.out.println(s1.equals(s2));//true String類覆寫 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...