Java Stream流学习日志

什么是Stream流?

在Java 8中,得益于Lambda所带来的函数式编程, 引入了一个全新的Stream流概念。
目的:用于简化集合和数组操作的API。

Stream流式思想的核心:

先得到集合或者数组的Stream流(就是一根传送带)
把元素放上去
然后就用这个Stream流简化的API来方便的操作元素。

Stream流的三类方法

获取Stream流

创建一条流水线,并把数据放到流水线上准备进行操作

中间方法

流水线上的操作。一次操作完毕之后,还可以继续进行其他操作。

终结方法

一个Stream流只能有一个终结方法,是流水线上的最后一个操作

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/*Stream<T> filter(Predicate<? super T> predicate)	用于对流中的数据进行过滤。

        Stream<T> limit(long maxSize)  获取前几个元素

        Stream<T> skip(long n)  跳过前几个元素

        Stream<T> distinct()去除流中重复的元素。依赖(hashCode和equals方法)

static <T> Stream<T> concat(Stream a, Stream b)合并a和b两个流为一个流*/

/*Stream<T> filter(Predicate<? super T> predicate)
        返回由与此给定谓词匹配的此流的元素组成的流。*/
public class Stream_01 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"lynk&co", "zeeker", "lotus", "polarstar");
        list.forEach(System.out::println);//forEach结合lambda表达式对集合的遍历
        System.out.println("=============");
        /*stream流 的一些基本使用   支持链式编程*/
        list.stream().filter(s -> s.startsWith("l")).forEach(System.out::println);
        System.out.println("=============");
        list.stream().filter(s -> s.startsWith("l")).filter(s -> s.length() > 6).forEach(System.out::println);
        Set<String> set = new HashSet<>();
        set.addAll(list);
        System.out.println("=============");
        System.out.println(set);

    }
}

运行结果:
在这里插入图片描述

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

/*Stream<T> filter(Predicate<? super T> predicate)	用于对流中的数据进行过滤。

Stream<T> limit(long maxSize)  获取前几个元素

Stream<T> skip(long n)  跳过前几个元素

Stream<T> distinct()去除流中重复的元素。依赖(hashCode和equals方法)

static <T> Stream<T> concat(Stream a, Stream b)合并a和b两个流为一个流

Stream<T> filter(Predicate<? super T> predicate)*/

/*static <T> Stream<T> of(T... values)
        返回其元素为指定值的顺序有序流。
        参数类型
        T - 流元素的类型
        参数
        values - 新流的元素
        结果
        新流*/
public class Stream_02 {
    public static void main(String[] args) {
        List<String> listComputer = new ArrayList<>();
        listComputer.add("数据结构");
        listComputer.add("计算机科学概论");
        listComputer.add("操作系统");
        listComputer.add("计算机组成原理");
        listComputer.add("软件工程");
        listComputer.add("软件测试");
        listComputer.add("软件测试");
        listComputer.add("计算机网络");
        listComputer.add("数字逻辑设计");
        listComputer.add("数字逻辑设计");
        System.out.println(listComputer);
        /*使用stream流 startsWith() 方法筛选出以计算开头的数据并且用forEach输出出来*/
        listComputer.stream().filter(s -> s.startsWith("计算")).forEach(s -> System.out.print(s + " "));
        System.out.println();
        System.out.println("============");
        /*使用stream流 startsWith() 方法筛选出以计算开头的数据并且去重 跳过一个元素  把剩下的元素用forEach输出出来*/
        listComputer.stream().filter(s -> s.startsWith("计算")).distinct().skip(1).forEach(s -> System.out.print(s + " "));
        System.out.println();
        System.out.println("============");
        /*使用stream流 distinct() 方法 给集合的元素去重*/
        listComputer.stream().distinct().forEach(s -> System.out.print(s + " "));
        System.out.println();
        System.out.println("============");
        /*使用stream流map()方法 对流中的内容进行操作 (lambda表达式简化代码)*/

        /*<R> Stream<R> map(Function<? super T,? extends R> mapper)
        返回一个流,该流包含将给定函数应用于此流的元素的结果。*/

        listComputer.stream().map(s -> "计算机基础课程 ;" + s).forEach(System.out::println);
        System.out.println("============");
        /*以下是未经过lambda表达式简化的原始代码*/
//        listComputer.stream().map(new Function<String, Object>() {
//            @Override
//            public Object apply(String s) {
//                return "计算机基础课程 : " + s;
//            }
//        }).forEach(t -> System.out.println(t));

        List<String> listMath = new ArrayList<>();
        Collections.addAll(listMath, "高等数学", "线性代数", "概率论与数理统计");
        Stream streamComputer = listComputer.stream();
        Stream streamMath = listMath.stream();
        /*Stream流先对第一个流去重 然后用 静态方法concat() 拼接两个流*/
        /*static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)*/
        //concat()方法用于拼接两个流
        Stream.concat(streamComputer,streamMath).distinct().forEach(s -> System.out.print(s + " "));

        /*注意:Stream流创建之后只能使用一次后自动销毁 想要再次使用只能重新创建  再次使用在运行时会报错*/
//        需求 :以上两个集合的课程加工成Lesson对象,
        Stream streamComputer1 = listComputer.stream();
        Stream streamMath1 = listMath.stream();
        ArrayList<Lesson> listLesson = new ArrayList<>();

        /*第一种自己的方法,用forEach遍历,略low*/
        Stream.concat(streamComputer1,streamMath1).forEach(s -> listLesson.add(new Lesson(s.toString())));
        System.out.println();
        System.out.println("============");
        System.out.println(listLesson);
        /*第二种方法,用map遍历*/
        Stream streamComputer2 = listComputer.stream();
        Stream streamMath2 = listMath.stream();
        Stream.concat(streamComputer2,streamMath2).map(s -> new Lesson(s.toString())).forEach(System.out::println);
        System.out.println("==============");

        /*static <T> Stream<T> of(T... values)
        返回其元素为指定值的顺序有序流。*/

        Stream<String> s = Stream.of("Javase", "JavaWeb");
        s.forEach(t -> System.out.println(t));


    }
}
class Lesson{
    private String name;

    public Lesson(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Lesson{" +
                "name='" + name + '\'' +
                '}';
    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述

//需求:某个公司的开发部门,分为开发一部和二部,现在需要进行年中数据结算。
//        分析:
//        :员工信息至少包含了(名称、性别、工资、奖金(假设每月都有奖金)、处罚记录)
//        :开发一部有4个员工、开发二部有5名员工
//        :分别筛选出2个部门的最高工资的员工信息,封装成优秀员工对象Topperformer
//        :分别统计出2个部门的平均月收入,要求去掉最高和最低工资。
//        :统计2个开发部门整体的平均工资,去掉最低和最高工资的平均值。

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Test {
    public static double allOneSalary;
    public static double allTwoSalary;
    public static double allSalary;

    public static void main(String[] args) {
        List<Employee> one = new ArrayList<>();
        one.add(new Employee("猪八戒", '男', 30000, 25000, null));
        one.add(new Employee("孙悟空", '男', 25000, 1000, "顶撞上司"));
        one.add(new Employee("沙僧", '男', 20000, 20000, null));
        one.add(new Employee("小白龙", '男', 20000, 25000, null));

        List<Employee> two = new ArrayList<>();
        two.add(new Employee("武松", '男', 15000, 9000, null));
        two.add(new Employee("李逵", '男', 20000, 10000, null));
        two.add(new Employee("西门庆", '男', 50000, 100000, "被打"));
        two.add(new Employee("潘金莲", '女', 3500, 1000, "被打"));
        two.add(new Employee("武大郎", '女', 20000, 0, "下毒"));
//        /*获得两个组的最高工资的员工*/
//        第一种写法 用sorted定义递减 比较规则  取第一个元素,用get()方法从流中获得这个元素(类型为Employee)
        Employee ee1 = one.stream().sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary()))).findFirst().get();
        Employee ee2 = two.stream().sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary()))).findFirst().get();
        System.out.println("一组的最高工资员工的信息为: " + ee1);
        System.out.println("二组的最高工资员工的信息为: " + ee2);
//        也可以如下写法 把以上的sorted换成 max 直接用get方法取元素即可
        Employee e1 = one.stream().max((o1, o2) -> Double.compare((o1.getBonus() + o1.getSalary()), (o2.getBonus() + o2.getSalary()))).get();
        System.out.println(e1);
        Employee e2 = two.stream().max((o1, o2) -> Double.compare((o1.getBonus() + o1.getSalary()), (o2.getBonus() + o2.getSalary()))).get();
        System.out.println(e2);


//        /*筛选出2个部门的最高工资的员工信息,封装成优秀员工对象Topperformer*/
        Stream.concat(one.stream()
                .sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary())))
                .findFirst().stream(), two.stream()
                .sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary())))
                .findFirst().stream()).map(s -> new Topperformer(s.getName(), s.getSalary() + s.getBonus()))
                .forEach(System.out::println);
//        /*分别统计出2个部门的平均工资,要求去掉最高和最低工资*/
        /*临时变量allSalary,allOneSalary和allTwoSalary都定义在 main方法外面,类里面*/
/*        原因: 1:定义在main里面的话,匿名类对象访问不到,因为匿名类也是一个方法,main方法的变量进不去
              2:定义在匿名类对象里面的话,因为是局部变量,参数不能带到main方法里面去*/
//        System.out.println("以下是一组工资排序");
//        one.stream()
//                .sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary())))
//                .forEach(a -> System.out.println(a.getSalary() + a.getBonus()));
//        System.out.println("以上是一组工资排序");
        one.stream()
                .sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary())))
                .skip(1).limit(one.size() - 2).forEach(s -> allOneSalary += (s.getSalary() + s.getBonus()));
//        System.out.println("开发一部的总工资" + allOneSalary);
        System.out.println("开发一部的平均月收入为: " + allOneSalary / (one.size() - 2));

//        System.out.println("以下是二组工资排序");
//        two.stream()
//                .sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary())))
//                .forEach(a -> System.out.println(a.getSalary() + a.getBonus()));
//        System.out.println("以上是二组工资排序");
        two.stream()
                .sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary())))
                .skip(1).limit(one.size() - 2).forEach(s -> allTwoSalary += (s.getSalary() + s.getBonus()));
//        System.out.println("开发二部的总工资" + allTwoSalary);
        System.out.println("开发二部的平均月收入为: " + allTwoSalary / (one.size() - 2));

//          统计2个开发部门整体的平均工资,去掉最低和最高工资的平均值
        BigDecimal bd = new BigDecimal(one.size() + two.size() - 2);
        Stream.concat(one.stream(), two.stream())
                .sorted((o1, o2) -> Double.compare((o2.getBonus() + o2.getSalary()), (o1.getBonus() + o1.getSalary())))
                .skip(1).limit(one.size() + two.size() - 2).forEach(s -> allSalary += (s.getSalary() + s.getBonus()));
        BigDecimal bd3 = new BigDecimal(allSalary);
        System.out.println("开发部所有人的平均月收入为: " + bd3.divide(bd, 2, RoundingMode.HALF_UP));
    }
}
public class Employee {
    private String name;
    private char sex;
    private double salary;
    private double bonus;//假设每月都有奖金
    private String punish; // 处罚信息

    public Employee() {
    }

    public Employee(String name, char sex, double salary, double bonus, String punish) {
        this.name = name;
        this.sex = sex;
        this.salary = salary;
        this.bonus = bonus;
        this.punish = punish;
    }

    public String getName() {
        return name;
    }

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

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    public String getPunish() {
        return punish;
    }

    public void setPunish(String punish) {
        this.punish = punish;
    }

    public double getTotalSalay() {
        return salary * 12 + bonus;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", salary=" + salary +
                ", bonus=" + bonus +
                ", punish='" + punish + '\'' +
                '}' + "\n";
    }
}
public class Topperformer {
    private String name;
    private double money; // 月薪

    public Topperformer() {
    }

    public Topperformer(String name, double money) {
        this.name = name;
        this.money = money;
    }

    public String getName() {
        return name;
    }

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

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Topperformer{" +
                "name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}



运行结果:
在这里插入图片描述

把Stream流操作后的结果数据转回到集合或者数组中去

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/*可以把Stream流操作后的结果数据转回到集合或者数组中去。

        public static <T> Collector toList()
        public static <T> Collector toSet()
        public static Collector toMap(Function keyMapper , Function valueMapper)
 */
public class StreamToCollection {
    public static void main(String[] args) {
        List<String> computerLesson = new ArrayList<>();
        computerLesson.add("数据结构");
        computerLesson.add("计算机科学概论");
        computerLesson.add("操作系统");
        computerLesson.add("计算机组成原理");
        computerLesson.add("软件工程");
        computerLesson.add("软件测试");
        computerLesson.add("软件测试");
        computerLesson.add("计算机网络");
        computerLesson.add("数字逻辑设计");
        computerLesson.add("数字逻辑设计");
        System.out.println(computerLesson);
        /*用List集合接收,Stream流*/
        List<String>list = computerLesson.stream().distinct().collect(Collectors.toList());
        System.out.println(list);
        /*用Set集合接收,Stream流*/
        Set<String> set = computerLesson.stream().collect(Collectors.toSet());
        //  简化后的语句:   Set<String> set = new HashSet<>(computerLesson);
        System.out.println(set);
        /*用数组接收 Stream流*/
        Object arr [] = computerLesson.stream().toArray();
        System.out.println(Arrays.toString(arr));
    }
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值