<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Java 中可以使用 java.util.Stream
對一個集合(實現了java.util.Collection
介面的類)做各種操作,例如:求和、過濾、排序等等。
這些操作可能是中間操作——返回一個 Stream 流,或者是終端操作——返回一個結果。
流操作並不會影響原來的集合,可以簡單認為,流操作是把集合中的一個元素逐個複製放到一個首尾相接的流動的水槽中。
Stream 流支援同步執行,也支援並行執行。如果我們直接獲取 stream 流,得到的是同步執行的 stream 流;如果呼叫方法 parallelStream
,則得到一個可以並行執行的 Stream 流。
注意:Map
不支援 Stream 流,但是它的 Key
和 Value
支援,因為它們實現了 Set
介面。
演示 Stream 流的提前準備,建立幾個類以供測試
public class MyUtil { private static List<String> list = new ArrayList<>(); private static List<Student> students = new ArrayList<>(); static { list.add("abc"); list.add("xyz"); list.add("fgh"); list.add("abc"); list.add("def"); list.add("xyz"); list.add("efg"); Student s1 = new Student(); s1.setAge("16"); s1.setId(UUID.randomUUID().toString()); s1.setName("張三"); s1.setMajor("電腦科學與技術"); Student s2 = new Student(); s2.setAge("18"); s2.setId(UUID.randomUUID().toString()); s2.setName("李四"); s2.setMajor("物聯網工程"); Student s3 = new Student(); s3.setAge("20"); s3.setId(UUID.randomUUID().toString()); s3.setName("王五"); s3.setMajor("網路工程"); students.add(s1); students.add(s2); students.add(s3); } public static List<String> getList() { return list; } public static List<Student> getStudents() { return students; } } public class Student { private String id; private String name; private String age; private String major; } public class StudentDTO { private String name; private String major; }
filter 可以幫助我們過濾流中的某些元素,其方法簽名如下
/* 過濾操作, Predicate 相當於一個謂詞,即斷言流中的元素滿足某個條件,返回一個 布林值 */ Stream<T> filter(Predicate<? super T> predicate);
具體使用方法如下:
public class Main { public static void main(String[] args) { List<String> list = MyUtil.getList(); System.out.println("過濾操作之前:"); System.out.println(list); // 過濾不以 a 開頭的字串,collect() 將流中的元素放到一個新的集合中 List<String> newList = list.stream().filter(s -> !s.startsWith("a")).collect(Collectors.toList()); System.out.println("-------------------------"); System.out.println("過濾操作之後:"); System.out.println(newList); } } ======== 輸出 ========= 過濾操作之前: [abc, xyz, fgh, abc, def, xyz, efg] ------------------------- 過濾操作之後: [xyz, fgh, def, xyz, efg]
sorted 可以幫助我們排序流中的元素,方法簽名如下:
/* 中間操作,傳入一個 Comparator,對流中的元素進行排序,如果不傳入,則使用預設的 Comparable 排序 對原集合不影響 */ Stream<T> sorted(Comparator<? super T> comparator);
具體使用方法如下:
public class Main { public static void main(String[] args) { List<String> list = MyUtil.getList(); System.out.println("排序操作之前:"); System.out.println(list); List<String> newList = list.stream().sorted().collect(Collectors.toList()); System.out.println("-------------------------"); System.out.println("排序操作之後:"); System.out.println(newList); System.out.println("自定義排序:"); // 倒序排序。 forEach 方法可以用傳入的方法 逐個 處理流中的元素 list.stream().sorted((s1, s2)-> -s1.compareTo(s2)).forEach(System.out::println); } } ======== 輸出 ========= 排序操作之前: [abc, xyz, fgh, abc, def, xyz, efg] ------------------------- 排序操作之後: [abc, abc, def, efg, fgh, xyz, xyz] 自定義排序: xyz xyz fgh efg def abc abc
Map 操作可以幫助我們將流中的一類元素對映為另一類元素,最典型的應用就是可以用來將資料庫實體類轉換為供前端使用的 DTO 類。方法簽名如下:
/* 中間操作,可以將一個物件轉化為另一個物件 例如做 DTO 資料轉換 */ <R> Stream<R> map(Function<? super T, ? extends R> mapper);
具體使用方法如下:
public class Main { public static void main(String[] args) { List<Student> students = MyUtil.getStudents(); System.out.println("map 操作之前"); System.out.println(students); // collect 方法可以將流中的元素收集到一個 Collection 中,如果有去除重複元素的需求,可以考慮收集到 Set 中 List<StudentDTO> dtos = students.stream().map(student -> { StudentDTO dto = new StudentDTO(); dto.setName(student.getName()); dto.setMajor(student.getMajor()); return dto; }).collect(Collectors.toList()); System.out.println("-------------------------"); System.out.println("map 操作之後"); System.out.println(dtos); } } ======== 輸出 ========= map 操作之前 [Student{id='cb5726cd-e73a-443e-95e5-155aa6e876ae', name='張三', age='16', major='電腦科學與技術'}, Student{id='94478bae-b2ee-4c43-bac0-12f45f4099cd', name='李四', age='18', major='物聯網工程'}, Student{id='5fdd9e19-f7cf-4c61-b506-0ef58a36dcbe', name='王五', age='20', major='網路工程'}] ------------------------- map 操作之後 [StudentDTO{name='張三', major='電腦科學與技術'}, StudentDTO{name='李四', major='物聯網工程'}, StudentDTO{name='王五', major='網路工程'}]
/* 終端操作,可以用來匹配操作,返回一個 boolean 值 可以方便地匹配集合中是否存在某種元素 */ // 只要集合中有一個匹配,就返回 true boolean anyMatch(Predicate<? super T> predicate); // 集合中所有元素都匹配,才返回 true boolean allMatch(Predicate<? super T> predicate); // 集合中所有元素都不匹配,返回 true boolean noneMatch(Predicate<? super T> predicate);
具體使用方法如下:
public class Main { public static void main(String[] args) { List<String> list = MyUtil.getList(); System.out.println("集合中的所有元素是否都以 a 開頭"); System.out.println(list.stream().allMatch(s -> s.startsWith("a"))); System.out.println("集合中是否存在元素以 a 開頭"); System.out.println(list.stream().anyMatch(s -> s.startsWith("a"))); System.out.println("集合中的元素是否都不以 a 開頭(相當於 allMatch 的取反):"); System.out.println(list.stream().noneMatch(s -> s.startsWith("a"))); } } ======== 輸出 ========= 集合中的所有元素是否都以 a 開頭 false 集合中是否存在元素以 a 開頭 true 集合中的元素是否都不以 a 開頭(相當於 allMatch 的取反): false
/* 終端操作,返回 stream 流中及集合中的元素個數,返回一個 long 型別 */ long count();
具體使用方法如下:
public class Main { public static void main(String[] args) { List<String> list = MyUtil.getList(); System.out.println(list); System.out.println("集合中的個數:" + list.size()); long count = list.stream().filter(s -> s.startsWith("a")).count(); System.out.println("集合中以 a 開頭的元素個數:" + count); } } ======== 輸出 ========= [abc, xyz, fgh, abc, def, xyz, efg] 集合中的個數:7 集合中以 a 開頭的元素個數:2
/* 終端操作,可以理解為減少集合的個數,對集合中的元素不斷進行累加,最終只得到一個元素 Optional 包含一個物件,可以防止空指標異常 */ Optional<T> reduce(BinaryOperator<T> accumulator);
具體使用方法如下:
public class Main { public static void main(String[] args) { List<String> list = MyUtil.getList(); // 可以理解為減少集合的個數,對集合中的元素不斷進行累加,最終只得到一個元素 // 例如對數位集合進行累加進行求和 String s = list.stream().reduce((s1, s2) -> s1 + "###" + s2).get(); System.out.println(s); } } ======== 輸出 ========= abc###xyz###fgh###abc###def###xyz###efg
可以看到,stream 流操作並沒有什麼使用難度,但如果不熟悉 Lambda 表示式開發和函數參照,則使用起來可能會稍微吃力些。
置於並行流的使用,只需要使用集合的方法parallelStream()
,就可以獲得一個並行流,在編寫程式碼上基本和同步流沒什麼區別,因此學會上面的基本用法基本足夠了,實際使用過程中,根據實際情況決定如何使用即可。
以上就是Java集合Stream流操作的基本使用教學分享的詳細內容,更多關於Java Stream流操作的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45