欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA8新特性-流(Stream)

程序员文章站 2022-04-28 21:26:34
...

java8新特性-流(stream)的基础操作

目录结构

JAVA8新特性-流(Stream)

Person:pojo对象

package com.dhh.data;


//Person类
public class Person implements Comparable<Person>{
    //姓名
    private String name;
    //性别
    private String gender;
    //年龄
    private int age;
    //成绩
    private int score;

    public String getName() {
        return name;
    }

    public Person setName(String name) {
        this.name = name;
        return this;
    }

    public int getAge() {
        return age;
    }

    public Person setAge(int age) {
        this.age = age;
        return this;
    }

    public int getScore() {
        return score;
    }

    public Person setScore(int score) {
        this.score = score;
        return this;
    }

    public String getGender() {
        return gender;
    }

    public Person setGender(String gender) {
        this.gender = gender;
        return this;
    }

    public Person(String name, int age, int score, String gender) {
        this.name = name;
        this.age = age;
        this.score = score;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", score='" + score + '\'' +
                '}';
    }

    public Person() {
    }

    @Override
    public int compareTo(Person o) {
        return this.getScore() - o.getScore();
    }
}

Data:数据源

package com.dhh.data;

import java.util.ArrayList;
import java.util.List;

//数据源
public class Data {
    public static List<Person> getData() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("小明", 12, 90, "男"));
        personList.add(new Person("小华", 13, 80, "女"));
        personList.add(new Person("小丁", 15, 85, "男"));
        personList.add(new Person("小李", 17, 40, "女"));
        personList.add(new Person("小毛", 18, 70, "男"));
        personList.add(new Person("小宁", 12, 60, "女"));
        //验证流操作会不会出现NPE异常
        Person null1 = new Person().setAge(12).setGender("女");
        Person null2 = new Person().setAge(12).setName("空2").setGender("女");
        personList.add(null1);
        personList.add(null2);
        return personList;
    }
}

Main:测试Demo

package com.dhh;

import com.dhh.data.Data;
import com.dhh.data.Person;

import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

//java8新特性:流的操作
public class Main {

    //三个步骤
    //1.获取数据源:集合 数组
    //2.对数据进行处理的过程:过滤 排序 映射... (中间操作)
    //3.对流中数据的整合:转成集合,数量...(最终操作)
    public static void main(String[] args) {
        //1.获取流: Stream<?> s = Data.getData().stream();
/**************************************************************************最终操作**************************************************/
        //2.最终操作1: collect,与 Collectors 配合使用 Collectors.toList() Collectors.toSet()
        //转成List
        List<Person> personList = Data.getData().stream().collect(Collectors.toList());
        System.out.println(personList);
        //转成set
        Set<Person> personSet = Data.getData().stream().collect(Collectors.toSet());
        System.out.println(personSet);
        //转成map (key为name,value为年龄),两种写法
        //TODO  转map时注意:key不可以重复 否则报错java.lang.IllegalStateException: Duplicate key
        Map<String, Integer> map = Data.getData().stream().collect(Collectors.toMap(i -> i.getName(), i -> i.getAge()));
        Map<String, Integer> map1 = Data.getData().stream().collect(Collectors.toMap(Person::getName, Person::getAge));
        System.out.println(map);
        System.out.println(map1);

        //3.最终操作2:reduce (Comparator接口,n1,n2为集合或数组中每个元素)
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Optional<Integer> optional = stream.reduce((n1, n2) -> n1 + n2);
        System.out.println(optional.get());
        //求所有学生的成绩总和
        Person temp = new Person();//实例化一个临时对象存放两个人成绩的和,避免重复创建对象浪费资源
        Optional<Person> reduce = Data.getData().stream().reduce((n1, n2) -> temp.setScore(n1.getScore() + n2.getScore()));
        System.out.println(reduce.get().getScore());

        //4.最终操作3:max和min(Comparator接口)
        //需求1:找到最高成绩的人的信息(若有两个相同最高成绩的,随机取一个)
        Optional<Person> max = Data.getData().stream().max((n1, n2) -> n1.getScore() - n2.getScore());//max()里面自定义大小比较的依据
        System.out.println(max.get());
        //需求2:找到最低成绩的人的信息(若有两个相同最高成绩的,随机取一个)
        Optional<Person> min = Data.getData().stream().min((n1, n2) -> n1.getScore() - n2.getScore());
        System.out.println(min.get());

        //5.最终操作4:anyMatch,allMatch,noneMatch
        //需求1:判断集合中是否存在成绩不合格的学生
        boolean anyMatch = Data.getData().stream().anyMatch(person -> person.getScore() < 60);//是否存在匹配的
        System.out.println(anyMatch);
        //需求2:判断集合中是否所有的同学成绩都合格
        boolean allMatch = Data.getData().stream().allMatch(person -> person.getScore() >= 60);//是否全部匹配
        System.out.println(allMatch);
        boolean noneMatch = Data.getData().stream().noneMatch(person -> person.getScore() < 60);//是否全部不匹配
        System.out.println(noneMatch);
        //6.最终操作5:count
        //需求:求元数据中有多少个元素
        long count = Data.getData().stream().count();
        System.out.println(count);

        //7.最终操作6 forEach
        Data.getData().stream().forEach(i -> System.out.println(i));

        //8.最终操作注意事项
        Stream<Person> stream1 = Data.getData().stream();
        Person maxPerson = stream1.max((n1, n2) -> n1.getScore() - n2.getScore()).get();
        // Person minPerson = stream1.min((n1, n2) -> n1.getScore() - n2.getScore()).get();
        //TODO  运行上面三行代码会报异常:Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
        //	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
        //	at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
        //	at java.util.stream.ReferencePipeline.min(ReferencePipeline.java:520)
        //	at com.dhh.Main.main(Main.java:71)
        //TODO 最终操作执行过后 流会被关闭,此时在对其做其他处理就会报异常。

        /*********************************************************************中间操作***********************************************/
        //中间操作1:filter
        //filter:是一个过滤器,可以自定义过滤一个条件,保留满足条件的元素。剔除不满足条件的元素
        //需求1:保留集合中所有成绩大于等于80的成员信息
        System.out.println("*********************************************************************中间操作***********************************************");
        Data.getData().stream().filter(person -> person.getScore() >= 80).forEach(i -> System.out.println(i));

        //中间操作2:distinct
        //distinct:去重 去除集合中重复的元素
        //去重规则:先判断hashcode(),如果hashcode()相同,再判断equals(),也相同 则认为元素重复。
        Data.getData().stream().distinct().forEach(i -> System.out.println(i));
        Stream<String> stream2 = Stream.of("1", "1", "2", "3", "4");
        stream2.distinct().forEach(i -> System.out.println(i));//输出 1 2 3 4

        //中间操作3:sorted
        //sorted:排序,对流中的元素进行排序,有参的排序优先级>无参类中实现的排序优先级
        //sorted():无参,要求流中的元素对应的类需要实现 comparable 接口【不常用】
        Data.getData().stream().sorted().forEach(i -> System.out.println(i));
        //sorted()有参【常用】
        Data.getData().stream().sorted((i1, i2) -> i1.getScore() - i2.getScore()).forEach(i -> System.out.println(i));

        //中间操作4:limit skip
        //limit:限制,只取流中前指定位的元素
        Data.getData().stream().limit(3).forEach(i -> System.out.println(i));//截取前三条数据
        //skip:跳过,跳过流中前指定位的元素,取后面的元素
        Data.getData().stream().skip(3).forEach(i -> System.out.println(i));//跳过前三条数据
        //需求1,获取集合元素中第2个到第10个元素
        Data.getData().stream().skip(1).limit(9).forEach(i -> System.out.println(i));


        //中间操作5:map
        //map: 元素映射,用指定的元素替换流中的元素
        //需求2:将流中的person对象替换成姓名
        Data.getData().stream().map(i -> i.getName()).forEach(i -> System.out.println(i));


        /****************************************************************测试练习***************************************************/
        /**
         *  需求:一个集合中存储了若干个Person对象,要求查询出一下结果
         *
         *  1.所有及格的学生的信息
         *  2.所有及格的学生的姓名
         *  3.班级的前三名(按照成绩)
         *  4.班级的3——10名(按照成绩)
         *  5.所有不及格的学生的平均成绩
         *  6.及格的学生,按照成绩的降序输出学生信息
         *  7.班级同学的总分
         */

        System.out.println("1.所有及格的学生的信息");
        System.out.println(Data.getData().stream().filter(i -> i.getScore() >= 60).collect(Collectors.toList()));
        System.out.println("2.所有及格的学生的姓名");
        System.out.println(Data.getData().stream().filter(i -> i.getScore() >= 60).map(m -> m.getName()).collect(Collectors.toList()));
        System.out.println("3.班级的前三名(按照成绩)");
        System.out.println(Data.getData().stream().sorted((n1, n2) -> n2.getScore() - n1.getScore()).limit(3).collect(Collectors.toList()));
        System.out.println("4.班级的3——10名(按照成绩)");
        System.out.println(Data.getData().stream().sorted((n1, n2) -> n2.getScore() - n1.getScore()).skip(2).limit(8).collect(Collectors.toList()));
        System.out.println("5.所有不及格的学生的平均成绩");
        long count1 = Data.getData().stream().filter(i -> i.getScore() < 60).count();
        Person temp1 = new Person();
        Optional<Person> reduce1 = Data.getData().stream().filter(i -> i.getScore() < 60).reduce((n1, n2) -> temp1.setScore(n1.getScore() + n2.getScore()));
        float avg = reduce1.get().getScore() / (float) count1;
        System.out.println(avg);
        System.out.println("6.及格的学生,按照成绩的降序输出学生信息");
        System.out.println(Data.getData().stream().filter(i -> i.getScore() >= 60).sorted((n1, n2) -> n2.getScore() - n1.getScore()).collect(Collectors.toList()));
        System.out.println("7.班级同学的总分");
        Optional<Person> reduce2 = Data.getData().stream().reduce((n1, n2) -> temp1.setScore(n1.getScore() + n2.getScore()));
        System.out.println(reduce2.get().getScore());

        //输出结果
        //1.所有及格的学生的信息
        //[Person{name='小明', gender='男', age=12, score='90'}, Person{name='小华', gender='女', age=13, score='80'}, Person{name='小丁', gender='男', age=15, score='85'}, Person{name='小毛', gender='男', age=18, score='70'}, Person{name='小宁', gender='女', age=12, score='60'}]
        //2.所有及格的学生的姓名
        //[小明, 小华, 小丁, 小毛, 小宁]
        //3.班级的前三名(按照成绩)
        //[Person{name='小明', gender='男', age=12, score='90'}, Person{name='小丁', gender='男', age=15, score='85'}, Person{name='小华', gender='女', age=13, score='80'}]
        //4.班级的3——10名(按照成绩)
        //[Person{name='小华', gender='女', age=13, score='80'}, Person{name='小毛', gender='男', age=18, score='70'}, Person{name='小宁', gender='女', age=12, score='60'}, Person{name='小李', gender='女', age=17, score='40'}, Person{name='null', gender='女', age=12, score='0'}, Person{name='空2', gender='女', age=12, score='0'}]
        //5.所有不及格的学生的平均成绩
        //13.333333
        //6.及格的学生,按照成绩的降序输出学生信息
        //[Person{name='小明', gender='男', age=12, score='90'}, Person{name='小丁', gender='男', age=15, score='85'}, Person{name='小华', gender='女', age=13, score='80'}, Person{name='小毛', gender='男', age=18, score='70'}, Person{name='小宁', gender='女', age=12, score='60'}]
        //7.班级同学的总分
        //425

    }
}

 

相关标签: java