欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java8中Stream的使用方式

 更新時(shí)間:2022年04月28日 10:17:41   作者:CoderJie?  
這篇文章主要介紹了Java8中Stream的使用方式,文章通過Stream的創(chuàng)建展開詳細(xì)的介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

前言:

相信有很多剛剛?cè)肟映绦騿T的小伙伴被一些代碼搞的很頭疼,這些代碼讓我們既感覺到很熟悉,又很陌生的感覺。我們很多剛?cè)胄械呐笥迅?xí)慣于使用for循環(huán)或是迭代器去解決一些遍歷的問題,但公司里很多老油子喜歡使用Java8新特性Stream流去做,這樣可以用更短的代碼實(shí)現(xiàn)需求,但是對(duì)于不熟悉的新手來(lái)說,可讀性差一些。

1. 為什么有經(jīng)驗(yàn)的老手更傾向于使用Stream

  • 性能優(yōu)勢(shì),(大數(shù)據(jù)量)相較于迭代器,速度更快
  • 支持串行與并行處理,并行處理更能充分利用CPU的資源
  • Stream 是一種計(jì)算數(shù)據(jù)的流,它本身不會(huì)存儲(chǔ)數(shù)據(jù)
  • 支持函數(shù)式編程
  • 代碼優(yōu)雅,讓代碼更高效,干凈,簡(jiǎn)潔

2. Stream 的使用方式

三步操作:

  • 創(chuàng)建Stream
  • 中間操作
  • 終止操作

3. Stream 的創(chuàng)建

Stream 的 創(chuàng)建都會(huì)依賴于數(shù)據(jù)源,通常是容器或者數(shù)組 Stream 流的創(chuàng)建大致分為4中,最為常用的就是通過集合創(chuàng)建

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class CreateStreamDemo {
    public static void main(String[] args) {
        // 1 通過集合創(chuàng)建Stream也是用的最多的一種形式
        List<String> strList = new ArrayList<>();
        strList.add("a");
        strList.add("b");
        strList.add("c");
        // 創(chuàng)建串行操作流
        Stream<String> stream = strList.stream();
        // 創(chuàng)建并行操作流
        Stream<String> parallelStream = strList.parallelStream();
        // 2 通過數(shù)組創(chuàng)建Stream
        int[] arr = new int[]{1,2,3};
        IntStream intStream = Arrays.stream(arr);
        // 3 通過Stream.of
        Stream<Integer> integerStream = Stream.of(1,2,3);
        Stream<String> stringStream = Stream.of("a","b","c");
        // 4 無(wú)限流
        // 每隔五個(gè)數(shù)取一個(gè)
        Stream.iterate(0, t -> t + 5).forEach(System.out::println); // 迭代
        Stream.generate(Math::random).forEach(System.out::println); // 生成
    }
}

4. Stream 中間操作

Stream 中間操作,我們最為常用的就是過濾,去重,排序 本章包含我們開發(fā)最常用的對(duì)對(duì)象的去重,和更據(jù)對(duì)象中的對(duì)個(gè)屬性組合排序

import com.zhj.java8.bean.Student;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Stream;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

public class MiddleStreamDemo {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1,"小華",23,1));
        students.add(new Student(1,"小華",23,2));
        students.add(new Student(2,"小米",20,2));
        students.add(new Student(3,"小果",30,3));
        students.add(new Student(4,"小維",18,2));
        // 過濾
        students.stream().filter(stu -> stu.getAge() > 20).forEach(System.out::println);
        // 去重
        // 對(duì)對(duì)象去重是根據(jù)引用去重,內(nèi)容重復(fù)并不會(huì)去重,除非重寫equals和hashCode方法
        System.out.println("----------去重----------");
        System.out.println("去重1----------");
        students.stream().distinct().forEach(System.out::println);
        // 對(duì)集合中對(duì)象某些屬性去重,不重寫equals和hashCode方法,只能借助其他數(shù)據(jù)結(jié)構(gòu)來(lái)輔助去重
        // 單個(gè)屬性可以stu -> stu.getId()
        // 多個(gè)屬性可以stu -> stu.getId() + ";" + stu.getName()
        System.out.println("去重2----------");
        ArrayList<Student> distinctList = students.stream().collect(
                collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(stu -> stu.getId() + ";" + stu.getName()))), ArrayList::new)
        );
        distinctList.stream().forEach(System.out::println);
        // 排序 支持定義排序方式
        // sorted 默認(rèn)使用 自然序排序, 其中的元素必須實(shí)現(xiàn)Comparable 接口
        System.out.println("----------排序----------");
        System.out.println("排序1----------");
        students.stream().sorted().forEach(System.out::println);
        // sorted(Comparator<? super T> comparator) :我們可以使用lambada 來(lái)創(chuàng)建一個(gè)Comparator 實(shí)例??梢园凑丈蚧蛑敌騺?lái)排序元素。
        System.out.println("排序2----------");
        students.stream()
                .sorted(Comparator.comparing(Student::getAge,Comparator.reverseOrder())) // ,Comparator.reverseOrder() 逆序
                .forEach(System.out::println);
        // 創(chuàng)建比較器,通過對(duì)比較器內(nèi)容的定義實(shí)現(xiàn)對(duì)多個(gè)屬性進(jìn)行排序,類似sql中連續(xù)的orderBy
        System.out.println("排序3----------");
        students.stream().sorted(
                (s1,s2) -> {
                    if (s1.getAge() == s2.getAge()) {
                        return s1.getSex().compareTo(s2.getSex());
                    } else {
                        return -s1.getAge().compareTo(s2.getAge());
                    }
                }
        ).forEach(System.out::println);
        System.out.println("排序4----------");
        Comparator<Student> studentComparator = (s1,s2) -> {
            Integer age1 = s1.getAge();
            Integer age2 = s2.getAge();
            if (age1 != age2) return age1 - age2;
            Integer sex1 = s1.getSex();
            Integer sex2 = s2.getSex();
            if (sex1 != sex2) return sex2 - sex1;
            return 0;
        };
        students.stream().sorted(studentComparator).forEach(System.out::println);
        // 截取 截取前三個(gè)元素
        System.out.println("----------截取----------");
        students.stream().limit(3).forEach(System.out::println);
        // 跳過 跳過前3個(gè)元素
        System.out.println("----------跳過----------");
        students.stream().skip(3).forEach(System.out::println);
        // 映射
        System.out.println("----------映射----------");
        System.out.println("映射Map----------");
        // map接收Lambda,將元素轉(zhuǎn)換其他形式,或者是提取信息,并將其映射成一個(gè)新的元素
        Stream<Stream<Student>> streamStream1 = students.stream().map(str -> filterStudent(str));
        streamStream1.forEach(sm -> sm.forEach(System.out::println));
        System.out.println("映射flatMap----------");
        // map接收Lambda,將流中的每一個(gè)元素轉(zhuǎn)換成另一個(gè)流,然后把所有流連成一個(gè)流 扁平化映射
        Stream<Student> studentStream2 = students.stream().flatMap(str -> filterStudent(str));
        studentStream2.forEach(System.out::println);
        // 消費(fèi)
        System.out.println("----------消費(fèi)----------");
        students.stream().peek(stu -> stu.setAge(100)).forEach(System.out::println);
    }
    public static Stream<Student> filterStudent(Student student) {
        student = new Student();
        return Stream.of(student);
    }
}

Student

public class Student implements Comparable<Student> {
    private Integer id;
    private String name;
    private Integer age;
    private Integer sex;
    public Student() {
    }
    public Student(Integer id, String name, Integer age, Integer sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    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 Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", sex=" + sex +
                '}';
    }
    @Override
    public int compareTo(Student o) {
        return this.getAge() - o.getAge();
    }
}

5. Stream 終止操作

Stream 的終止操作,最常用的就是講處理過的數(shù)據(jù)收集到新的容器中,同時(shí)可以實(shí)現(xiàn)向Sql聚合函數(shù),分組的一些效果

package com.zhj.java8.stream;
import com.zhj.java8.bean.Student;
import java.util.*;
import java.util.stream.Collectors;
public class TerminationStreamDemo {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1,"小華",23,1));
        students.add(new Student(2,"小米",20,2));
        students.add(new Student(3,"小果",30,3));
        students.add(new Student(4,"小維",18,2));
        students.add(new Student(5,"小華",23,2));
        System.out.println("--------------------匹配聚合操作--------------------");
        // allMatch:接收一個(gè) Predicate 函數(shù),當(dāng)流中每個(gè)元素都符合該斷言時(shí)才返回true,否則返回false
        boolean allMatch = students.stream().allMatch(stu -> stu.getAge() > 10);
        System.out.println("全部符合大于10歲條件:" + allMatch);
        // noneMatch:接收一個(gè) Predicate 函數(shù),當(dāng)流中每個(gè)元素都不符合該斷言時(shí)才返回true,否則返回false
        boolean noneMatch = students.stream().noneMatch(stu -> stu.getAge() > 10);
        System.out.println("全部不符合大于10歲條件:" + noneMatch);
        // anyMatch:接收一個(gè) Predicate 函數(shù),只要流中有一個(gè)元素滿足該斷言則返回true,否則返回false
        boolean anyMatch = students.stream().anyMatch(stu -> stu.getAge() > 20);
        System.out.println("含有任意符合大于20歲條件:" + anyMatch);
        // findFirst:返回流中第一個(gè)元素
        Student findFirst = students.stream().findFirst().get();
        System.out.println("第一個(gè)學(xué)生:" + findFirst);
        // findAny:返回流中的任意元素
        Student findAny = students.stream().findAny().get();
        System.out.println("任意一個(gè)學(xué)生:" + findAny);
        //  count:返回流中元素的總個(gè)數(shù)
        long count = students.stream().count();
        System.out.println("學(xué)生總數(shù):" + count);
        // max:返回流中元素最大值
        Student max = students.stream().max(Student::compareTo).get();
        System.out.println("年齡最大學(xué)生:" + max);
        // max:返回流中元素最大值
        Student min = students.stream().min(Student::compareTo).get();
        System.out.println("年齡最小學(xué)生:" + min);
        System.out.println("--------------------規(guī)約操作--------------------");
        System.out.println("學(xué)生年齡總和:" + students.stream().map(Student::getAge).reduce(Integer::sum));
        System.out.println("學(xué)生年齡最大:" + students.stream().map(Student::getAge).reduce(Integer::max));
        System.out.println("--------------------收集操作--------------------");
        List<Student> list = students.stream().collect(Collectors.toList());
        Set<Student> set = students.stream().collect(Collectors.toSet());
        Map<Integer, String> map = students.stream().collect(Collectors.toMap(Student::getId, Student::getName));
        String joinName = students.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")"));
        // 總數(shù)
        students.stream().collect(Collectors.counting());
        // 最大年齡
        students.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get();
        // 年齡和
        students.stream().collect(Collectors.summingInt(Student::getAge));
        // 平均年齡
        students.stream().collect(Collectors.averagingDouble(Student::getAge));
        // 信息合集
        DoubleSummaryStatistics statistics = students.stream().collect(Collectors.summarizingDouble(Student::getAge));
        System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
        // 分組
        Map<Integer, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getSex));
        System.out.println(collect);
        //多重分組,先根據(jù)性別分再根據(jù)年齡分
        Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));
        //分區(qū)
        //分成兩部分,一部分大于20歲,一部分小于等于20歲
        Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 20));
        //規(guī)約
        Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get();
        System.out.println(allAge);
    }
}

6. Stream 特性

中間操作惰性執(zhí)行

多個(gè)中間操作的話,不會(huì)多次循環(huán),多個(gè)轉(zhuǎn)換操作只會(huì)在終止操作的時(shí)候融合起來(lái),一次循環(huán)完成

  • 內(nèi)部迭代
  • 找到符合條件的數(shù)據(jù)后邊的迭代不會(huì)進(jìn)行
  • 流的末端操作只有一次

異常:stream has already been operated upon or closed

意思是流已經(jīng)被關(guān)閉了,這是因?yàn)楫?dāng)我們使用末端操作之后,流就被關(guān)閉了,無(wú)法再次被調(diào)用,如果我們想重復(fù)調(diào)用,只能重新打開一個(gè)新的流。

到此這篇關(guān)于Java8中Stream的使用方式的文章就介紹到這了,更多相關(guān)Java8中的Stream內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring注解之@PropertySource詳解

    Spring注解之@PropertySource詳解

    這篇文章主要介紹了Spring注解之@PropertySource詳解,@PropertySource注解用于指定資源文件讀取的位置,它不僅能讀取properties文件,也能讀取xml文件,并且通過YAML解析器,配合自定義PropertySourceFactory實(shí)現(xiàn)解析YAML文件,需要的朋友可以參考下
    2023-11-11
  • 使用java實(shí)現(xiàn)猜拳小游戲

    使用java實(shí)現(xiàn)猜拳小游戲

    這篇文章主要為大家詳細(xì)介紹了使用java實(shí)現(xiàn)猜拳小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • spring boot 錯(cuò)誤頁(yè)面配置解決方案

    spring boot 錯(cuò)誤頁(yè)面配置解決方案

    這篇文章主要介紹了spring boot 錯(cuò)誤頁(yè)面配置解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • mybatis對(duì)傳入基本類型參數(shù)的判斷方式

    mybatis對(duì)傳入基本類型參數(shù)的判斷方式

    這篇文章主要介紹了mybatis對(duì)傳入基本類型參數(shù)的判斷方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java中調(diào)用GDAL DLL的實(shí)現(xiàn)方法

    java中調(diào)用GDAL DLL的實(shí)現(xiàn)方法

    本篇文章是對(duì)java中調(diào)用GDAL DLL的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 利用JAVA反射,讀取數(shù)據(jù)庫(kù)表名,自動(dòng)生成對(duì)應(yīng)實(shí)體類的操作

    利用JAVA反射,讀取數(shù)據(jù)庫(kù)表名,自動(dòng)生成對(duì)應(yīng)實(shí)體類的操作

    這篇文章主要介紹了利用JAVA反射,讀取數(shù)據(jù)庫(kù)表名,自動(dòng)生成對(duì)應(yīng)實(shí)體類的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-08-08
  • 詳解Java如何優(yōu)雅的實(shí)現(xiàn)異常捕獲

    詳解Java如何優(yōu)雅的實(shí)現(xiàn)異常捕獲

    在一個(gè)優(yōu)秀的項(xiàng)目中一定少不了對(duì)程序流程良好的異常捕獲與日志打印,所以本文主要為大家介紹了如何優(yōu)雅的實(shí)現(xiàn)異常捕獲與日志打印輸出,有需要的可以參考下
    2023-09-09
  • java中堆和棧的區(qū)別分析

    java中堆和棧的區(qū)別分析

    這篇文章主要介紹了java中堆和棧的區(qū)別,分析了Java中堆和棧的原理及使用時(shí)的注意事項(xiàng),需要的朋友可以參考下
    2014-09-09
  • Spring學(xué)習(xí)筆記之bean生命周期

    Spring學(xué)習(xí)筆記之bean生命周期

    Spring Bean是Spring應(yīng)用中最最重要的部分了。下面這篇文章主要給大家介紹了關(guān)于Spring學(xué)習(xí)筆記之bean生命周期的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-12-12
  • 使用Java反射機(jī)制提高SpringBoot的代碼質(zhì)量和可維護(hù)性

    使用Java反射機(jī)制提高SpringBoot的代碼質(zhì)量和可維護(hù)性

    保持好的代碼質(zhì)量和遵守編碼標(biāo)準(zhǔn)是開發(fā)可維護(hù)和健壯軟件的重要方面,在本文中,我們將探討如何使用 Java 反射來(lái)提高 Spring Boot 應(yīng)用程序的代碼質(zhì)量和可維護(hù)性,需要的朋友可以參考下
    2023-10-10

最新評(píng)論