日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Java函数式编程学习——Stream流

發布時間:2023/12/9 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java函数式编程学习——Stream流 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

概述

案例數據準備

1. 常用操作

2. 中間操作

filter

?map

?distinct

?sorted

limit

skip

flatMap

3. 終結操作

foreach

?count

max & min

collect

?anyMatch

?allMatch

noneMatch

findAny

findFirst

注意事項

(以下學習資料來自b站up主?三更草堂

概述

? ? ? ?Java8 的 Stream 使用的是函數式編程模式,如同它的名字一樣,它可以被用來對集合或數組進行鏈狀流式的操作??梢愿奖愕淖屛覀儗匣驍到M操作。

案例數據準備

引入依賴

<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency></dependencies>

Author實體類

@Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode//用于后期的去重使用 public class Author {//idprivate Long id;//姓名private String name;//年齡private Integer age;//簡介private String intro;//作品private List<Book> books; }

Book實體類

@Data @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode//用于后期的去重使用 public class Book {//idprivate Long id;//書名private String name;//分類private String category;//評分private Integer score;//簡介private String intro;}

插入數據

private static List<Author> getAuthors() {//數據初始化Author author = new Author(1L,"蒙多",33,"一個從菜刀中明悟哲理的祖安人",null);Author author2 = new Author(2L,"亞拉索",15,"狂風也追逐不上他的思考速度",null);Author author3 = new Author(3L,"易",14,"是這個世界在限制他的思維",null);Author author4 = new Author(3L,"易",14,"是這個世界在限制他的思維",null);//書籍列表List<Book> books1 = new ArrayList<>();List<Book> books2 = new ArrayList<>();List<Book> books3 = new ArrayList<>();books1.add(new Book(1L,"刀的兩側是光明與黑暗","哲學,愛情",88,"用一把刀劃分了愛恨"));books1.add(new Book(2L,"一個人不能死在同一把刀下","個人成長,愛情",99,"講述如何從失敗中明悟真理"));books2.add(new Book(3L,"那風吹不到的地方","哲學",85,"帶你用思維去領略世界的盡頭"));books2.add(new Book(3L,"那風吹不到的地方","哲學",85,"帶你用思維去領略世界的盡頭"));books2.add(new Book(4L,"吹或不吹","愛情,個人傳記",56,"一個哲學家的戀愛觀注定很難把他所在的時代理解"));books3.add(new Book(5L,"你的劍就是我的劍","愛情",56,"無法想象一個武者能對他的伴侶這么的寬容"));books3.add(new Book(6L,"風與劍","個人傳記",100,"兩個哲學家靈魂和肉體的碰撞會激起怎么樣的火花呢?"));books3.add(new Book(6L,"風與劍","個人傳記",100,"兩個哲學家靈魂和肉體的碰撞會激起怎么樣的火花呢?"));author.setBooks(books1);author2.setBooks(books2);author3.setBooks(books3);author4.setBooks(books3);List<Author> authorList = new ArrayList<>(Arrays.asList(author,author2,author3,author4));return authorList;}

需求一:

我們可以調用getAuthors方法獲取到作家的集合。現在需要打印所有年齡小于18的作家的名字,并且要注意去重。

List<Author> authors = getAuthors();//System.out.println(authors);authors.stream() //把集合轉換成流.distinct() //去重.filter(new Predicate<Author>() { //進行過濾 根據條件@Overridepublic boolean test(Author author) {return author.getAge() < 18;}}).forEach(new Consumer<Author>() { //打印出來@Overridepublic void accept(Author author) {System.out.println(author.getName());}});}

將匿名內部類轉換為lambda表達式:

List<Author> authors = getAuthors();//System.out.println(authors);//打印出來//進行過濾 根據條件authors.stream() //把集合轉換成流.distinct() //去重.filter(author -> author.getAge() < 18).forEach(author -> System.out.println(author.getName()));}

輸出結果:

Connected to the target VM, address: '127.0.0.1:50848', transport: 'socket' 亞拉索 易

進入debug模式查看,查看去重,過濾后的結果:

1. 常用操作

目錄

概述

案例數據準備

單列集合:集合對象.stream()?

List<Author> authors = getAuthors();Stream<Author> stream = authors.stream();

?數組:Arrays.strean()

Integer[] arr = {1,2,3,4,5};Stream<Integer> stream = Arrays.stream(arr); //傳入一個數組,返回一個流對象stream.distinct().forEach(integer -> System.out.println("數字="+integer)); Integer[] arr = {1,2,3,4,5};//Stream<Integer> stream = Arrays.stream(arr); //傳入一個數組,返回一個流對象Stream<Integer> arr1 = Stream.of(arr); //也可以用這種方式將數組轉換為stream流arr1.distinct().forEach(integer -> System.out.println("數字="+integer));

雙列集合:轉換為單列集合后再創建 (Map)

Map<String,Integer> map = new HashMap<>();map.put("蠟筆小新",19);map.put("黑子",17);map.put("日向翔陽",16);//將map轉換為單列集合 SetSet<Map.Entry<String, Integer>> entrySet = map.entrySet();Stream<Map.Entry<String, Integer>> stream = entrySet.stream();stream.filter(entry -> entry.getValue() > 16).forEach(stringIntegerEntry -> System.out.println(stringIntegerEntry.getKey()+"="+stringIntegerEntry.getValue()));

2. 中間操作

filter

需求:打印所有姓名長度大于1的作家的姓名

List<Author> authors = getAuthors();authors.stream().filter(author -> author.getName().length() > 1).forEach(author -> System.out.println(author.getName()));

?map

可以把流當中的元素進行計算或轉換

需求:打印所有作家的姓名

方式一:直接用foreach打印

List<Author>authors = getAuthors();authors.stream().forEach(author -> System.out.println(author.getName()));

方式二:將流當中的Author類型轉換為String類型輸出

Function方法中第一個泛型的類型必須和流當中的類型一致

List<Author>authors = getAuthors();//把流當中的元素進行類型轉換 第一個參數一般不變,第二個參數是要把流當中的元素轉換成什么,比如只是姓名(String)authors.stream().map(new Function<Author, String>() {@Override//參數是第一個定義的類型 Author ,方法返回值是 Stringpublic String apply(Author author) {return author.getName();}}).forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});

轉換為lambda

authors.stream().map(author -> author.getName()).forEach(s -> System.out.println(s));

?distinct

去除流中重復的元素

依賴的是Object.equals()方法來判斷是否是重復的對象。所以注意需要重寫equals方法。

需求:打印所有作家的姓名,并且要求其中不能有重復元素。

List<Author> authors = getAuthors();authors.stream().distinct().forEach(author -> System.out.println(author.getName()));

?sorted

需求:對流當中的元素進行排序,按照年齡來排序,降序,要求不能有重復元素

注意:如果調用空參的sorted()方法,需要流中的元素是實現了Comparable接口的。

public class Author implements Comparable<Author>{private Long id;private String name;private Integer age;private String intro;private List<Book> books;@Overridepublic int compareTo(Author o) {return o.getAge()- this.getAge() ;} } List<Author> authors = getAuthors();authors.stream().distinct().sorted().forEach(author -> System.out.println(author.getAge()));

使用sort的有參的方法

List<Author> authors = getAuthors();authors.stream().distinct().sorted(new Comparator<Author>() {@Overridepublic int compare(Author o1, Author o2) {return o2.getAge()- o1.getAge();}}).forEach(author -> System.out.println(author.getAge()));}

limit

可以設置流的最大長度,超出的部分將被拋棄

需求:對流中的元素按照年齡進行降序排序,并且要求不能有重復的元素,然后打印其中年齡最大的兩個作家的姓名。

List<Author> authors = getAuthors();authors.stream().distinct().sorted().limit(2).forEach(author -> System.out.println(author.getName()));

skip

跳過流中的前n個元素,返回剩下的元素

需求:打印除了年齡最大的作家外的其他作家,要求不能有重復元素,并且按照年齡降序排序。

List<Author> authors = getAuthors();authors.stream().distinct().sorted().skip(1) //跳過第一個元素 從1 開始.forEach(author -> System.out.println(author.getName()));}

flatMap

map只能把一個對象轉換成另一個對象來作為流中的元素。而flatMap可以把一個對象轉換成多個對象作為流中的元素。

需求一:打印所有書籍的名字。要求對重復的元素進行去重。

如果直接getBooks() ,拿到的都是book的list集合,而不是book對象

authors.stream().map(author -> author.getBooks()).forEach(new Consumer<List<Book>>() {@Overridepublic void accept(List<Book> books) {System.out.println(books);}});

如果希望流當中的元素都變成book對象,需要用flatMap

?要求返回的類型是 Stream流對象

authors.stream().flatMap(new Function<Author, Stream<Book>>() {@Overridepublic Stream<Book> apply(Author author) {return author.getBooks().stream(); //先獲取集合,再將集合轉換為流對象}}).distinct().forEach(new Consumer<Book>() {@Overridepublic void accept(Book book) {System.out.println(book.getName());}});

?需求二: 打印現有數據的所有分類。要求對分類進行去重。不能出現這種格式:哲學,愛情

List<Author> authors = getAuthors();authors.stream().flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream()).distinct().flatMap(book -> Arrays.stream(book.getCategory().split(",")))//將目錄按照,分割,然后放到數組里,再轉換成stream流,里面元素都是String類型.distinct() //對分類進行去重.forEach(category -> System.out.println(category));

?

3. 終結操作

foreach

對流當中的元素進行遍歷操作,我們通過傳入的參數去指定對遍歷的元素進行什么具體的操作。

authors.stream().map(author -> author.getName()).distinct().forEach(name -> System.out.println(name));}

?count

?用來獲取當前流中元素的個數。

需求:打印這些作家的所出書籍的數目,注意刪除重復元素。

private static void test13() {//要讓流中的元素是書List<Author> authors = getAuthors();long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();System.out.println(count);}

max & min

取流中的最值

需求:分別獲取這些作家的所出書籍的最高分和最低分并打印。

List<Author> authors = getAuthors();Optional<Integer> max = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).max((score1, score2) -> score1 - score2);Optional<Integer> min = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).min(new Comparator<Integer>() {@Overridepublic int compare(Integer score1, Integer score2) {return score1 - score2;}});System.out.println(max.get());System.out.println(min.get());

collect

把當前流轉換為一個集合

需求一:獲取一個存放所有作者名字的 List 集合

private static void test15() {List<Author> authors = getAuthors();List<String> nameList= authors.stream().map(author -> author.getName()).collect(Collectors.toList());System.out.println(nameList);} [蒙多, 亞拉索, 易, 易]

需求二:獲取一個存放所有作者名字的 Set集合

private static void test16() {List<Author> authors = getAuthors();Set<String> nameSet = authors.stream().map(author -> author.getName()).collect(Collectors.toSet());System.out.println(nameSet);} [亞拉索, 蒙多, 易]

需求三:獲取一個map集合,map的key為作者名,value為List<Book>

List<Author> authors = getAuthors();Map<String, List<Book>> map = authors.stream().distinct().collect(Collectors.toMap(new Function<Author, String>() {@Overridepublic String apply(Author author) {return author.getName();}}, new Function<Author, List<Book>>() {@Overridepublic List<Book> apply(Author author) {return author.getBooks();}}));System.out.println(map);

?查找和匹配

?anyMatch

可以用來判斷是否有任意符合匹配條件的元素,結果為boolean類型。

需求:判斷是否有年齡在29以上的作家

List<Author> authors = getAuthors();boolean b = authors.stream().anyMatch(new Predicate<Author>() {@Overridepublic boolean test(Author author) {return author.getAge() > 29;}});System.out.println(b);

?

?allMatch

可以用來判斷是否都符合匹配條件,結果為boolean類型。如果都符合結果為true,否則結果為false。

需求:判斷是否所有的作家都是成年人?

List<Author> authors = getAuthors();boolean b = authors.stream().allMatch(new Predicate<Author>() {@Overridepublic boolean test(Author author) {return author.getAge() >= 18;}});System.out.println(b);

noneMatch

可以判斷流中的元素是否都不符合匹配條件。如果都不符合結果為true,否則結果為false

findAny

獲取流中的任意一個元素。該方法沒有辦法保證獲取的一定是流中的第一個元素。

需求:獲取任意一個年齡大于18的作家,如果存在就輸出他的名字? 返回的對象是Optional<Author>

private static void test20() {List<Author> authors = getAuthors();Optional<Author> any = authors.stream().filter(author -> author.getAge() > 18).findAny();any.ifPresent(new Consumer<Author>() {@Overridepublic void accept(Author author) {System.out.println(author.getName());}});} 蒙多

findFirst

獲取流中的第一個元素。

需求:獲取一個年齡最小的作家,并輸出他的姓名。

先按sorted排序,按年齡從小到大,然后獲取第一個。

private static void test21() {List<Author> authors = getAuthors();Optional<Author> first = authors.stream().sorted(new Comparator<Author>() {@Overridepublic int compare(Author o1, Author o2) {return o1.getAge() - o2.getAge();}}).findFirst();first.ifPresent(new Consumer<Author>() {@Overridepublic void accept(Author author) {System.out.println(author.getName() + author.getAge());}});} 易14

?改成 o2 -o1 獲取的就是第一個年齡最大的

對流中的數據按照你指定的計算方式計算出一個結果。?(縮減操作)

reduce的作用是把stream中的元素給組合起來,我們可以傳入一個初始值,它會按照我們的計算方式依次拿流中的元素和初始化值進行計算,計算結果再和后面的元素計算。

reduce兩個參數的重載形式內部的計算方式如下:

其中identity就是我們可以通過方法參數傳入的初始值,accumulator的apply具體進行什么計算也是我們通過方法參數來確定的。

T result = identity; for (T element : this stream)result = accumulator.apply(result, element) return result;

需求一:使用reduce求所有作者年齡的和

private static void test22() {List<Author> authors = getAuthors();Integer sum = authors.stream().map(author -> author.getAge()).reduce(0, new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer result, Integer element) {return result + element;}});System.out.println(sum);}

需求二: 使用reduce求所有作者中年齡的最大值

先將Author 流 轉換為Integer類型的流 然后使用reduce 找到最大年齡

private static void test23() {List<Author> authors = getAuthors();Integer reduce = authors.stream().map(author -> author.getAge()).reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer result, Integer element) {return element > result ? element : result;}});System.out.println(reduce);}

需求三:使用reduce求所有作者中年齡的最小值

private static void test24() {List<Author> authors = getAuthors();Integer reduce = authors.stream().map(author -> author.getAge()).reduce(Integer.MAX_VALUE, new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer result, Integer element) {return result > element ? element : result;}});System.out.println(reduce);}

一個參數的重載形式內部的計算:

boolean foundAny = false;T result = null;for (T element : this stream) {if (!foundAny) {foundAny = true;result = element;}elseresult = accumulator.apply(result, element);}return foundAny ? Optional.of(result) : Optional.empty();

注意事項

  • 惰性求值? ? ? ? ? ? ? 如果沒有終結操作,中間的操作是不會被執行的
  • 流是一次性的? ? ? ?一個流對象經過一次終結操作以后,就不能再被使用
  • 不會影響原數據? ?我們再流中可以對數據做很多處理,但是正常情況下是不會影響原來集合中的元素的。

總結

以上是生活随笔為你收集整理的Java函数式编程学习——Stream流的全部內容,希望文章能夠幫你解決所遇到的問題。

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