Bootstrap

(二十八)Stream流

目录

前言:

        一、Stream流的获取方法

二、Stream流的中间操作方法

三、Stream流的终结方法


前言:

        1.什么是Stream流

                在java8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念。

                目的:

                        用于简化集合和数组操作的API。

        2.Stream流的作用是什么,结合了什么技术?

                简化了集合,数组操作的API,结合了Lambda表达式。

        3.Stream流的思想和使用步骤。

                ①先得到集合或者数组的Stream流(就是一根传送带);

                ②把元素放上去;

                ③然后用这个Stream流简化的API来方便的操作元素;

        4.Stream流的三类方法。

        ①获取Stream流

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

        ②中间方法

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

        ③终结方法

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

一、Stream流的获取方法

5.集合获取Stream流的方式

        可以使用Collection接口中的默认方法Stream()生成流。

6.数组获取Stream流的方式

二、Stream流的中间操作方法

7.Stream流的常用API

三、Stream流的终结方法

8.Stream流的终结方法API

S

        注意:

                终结操作方法,调用完成后流就无法继续使用了,原因是不会返回Stream流了。

9.代码演示:

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
​
/** Stream流   简化集合和数组的API  结合了Lambda表达式  支持链式编程
 *Stream的获取 : Collection 默认stream()生成流
 * API
 * filter()  过滤流中数据
 * limit(long maxSize)  获取前几个元素
 * skip(long n)  跳过前几个元素
 * distinct()  去掉重复的元素
 * concat(Stream a,Stream b)  合并a和b两个流为一个流
 * compare  比较器
 * 收集Stream  :就是把Stream流操作后的数据转回到集合或者数组中去。
 * collect(Collector,collector)
 */
public class Stream_Demo7 {
    public static void main(String[] args) {
        List<String> lists = new ArrayList<>();
        lists.add("张无忌");
        lists.add("周芷若");
        lists.add("张三");
        lists.add("李四");
        lists.add("王五");
        Collections.addAll(lists,"张强","赵敏","张三丰");
        System.out.println(lists);
​
        //找名字为张的名字
        List<String> zhanglist = new ArrayList<>();
        for (String list : lists) {
            if (list.startsWith("张")){
                zhanglist.add(list);
            }
        }
        System.out.println(zhanglist);
        //找名字长度是3的名字,的张姓名字
        List<String> Threelist = new ArrayList<>();
        for (String list : zhanglist) {
            if (list.length()  == 3){
                Threelist.add(list);
            }
        }
        System.out.println(Threelist);
        System.out.println("=====================================");
        //3.Stream流实现  过滤
        lists.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
        //总数
        long size =lists.stream().filter(s -> s.length() == 3).count();
        System.out.println(size);
        //取前几个名字
        lists.stream().filter(s -> s.startsWith("张")).limit(2).forEach(s -> System.out.println(s));
        //跳过前几个名字
        lists.stream().filter(s -> s.startsWith("张")).skip(1).forEach(s -> System.out.println(s));
        //Map加工方法  给集合元素的前面都加上:黑马的: 。
        lists.stream().map(s -> "黑马的:"+s).forEach(s -> System.out.println(s));
​
        System.out.println("=========================");
        //合并两个流
        Stream<String> s1 = lists.stream().filter(s -> s.startsWith("张"));
        Stream<String> s2 = Stream.of("JAVA","Python","Html");
        Stream<Object> s3 = Stream.concat(s1,s2);//只能合并两个流
        s3.forEach(s-> System.out.println(s));
​
​
        //获取流
        //Collection 的Stream流的获取
        Collection<String> list = new ArrayList<>();
        Stream<String> stream =list.stream();
​
        //Map 的Stream流的获取
        Map<String,Integer> map = new HashMap<>();
        //键流
        Stream<String> keystream =map.keySet().stream();
        //值流
        Stream<Integer> valuestream =map.values().stream();
        //键值对流(整体)
        Stream<Map.Entry<String,Integer>> keyandvalue =map.entrySet().stream();
​
        //数组Stream流的获取
        String[] names = {"赵敏","小昭","刘备"};
        //方法一
        Stream<String>namesstream1 =Arrays.stream(names);
        //方法二
        Stream<String>namesstream2 = Stream.of(names);
​
        System.out.println("====================================");
        // 收集Stream collect(Collector,collector)  :就是把Stream流操作后的数据转回到集合或者数组中去。
        List<String> ls = new ArrayList<>();
        ls.add("张无忌");
        ls.add("周芷若");
        ls.add("张三");
        ls.add("李四");
        ls.add("王五");
        Collections.addAll(ls,"张强","赵敏","张三丰");
        System.out.println(ls);
​
        Stream<String> s5 = ls.stream().filter(s ->s.startsWith("张"));
        List<String> zhangstream1 = s5.collect(Collectors.toList());
        System.out.println(zhangstream1);
​
        //注意: 流只能使用一次
        Stream<String> s4 = ls.stream().filter(s ->s.startsWith("张"));//再建一个流
        Set<String> zhangset = s4.collect(Collectors.toSet());
        System.out.println(zhangset);
​
        System.out.println("======================");
        Stream<String> s7 = ls.stream().filter(s ->s.startsWith("张"));
       String[] arrs = s7.toArray(String[]::new);//扩展,可以不用
        System.out.println("Arrays数组内容:"+Arrays.toString(arrs));
    }
}

10.案例

        需求:

                某公司的开发部门,分为开发一部和二部,现在需要进行年中数据结算。

        分析:

                ①员工信息至少包含两(名称,性别,工资,奖金,处罚记录);

                ②开发一部有4个员工,开发二部有5名员工;

                ③分别筛选出2个部门的最高工资的员工信息;

职员类:

public class Employee {
    private String name;
    private char sex;
    private double salary;
    private double bonus;//奖金
    private String punish;//处罚记录
​
    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;
    }
​
    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", salary=" + salary +
                ", bonus=" + bonus +
                ", punish='" + punish + '\'' +
                '}';
    }
}

Topperformer类:

public class Topperformer {
    private String name;
    private double money;//月薪
​
    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 +
                '}';
    }
}

Test类:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
​
public class Stream_Teat {
    public static double allMoney;
    public static double allMoney2;//两个部门的总和
    public static void main(String[] args) {
        List<Employee> one = new ArrayList<>();
        one.add(new Employee("张三",'男',30000,25000,null));
        one.add(new Employee("李四",'男',30000,2500,null));
        one.add(new Employee("王五",'男',15000,25000,null));
        one.add(new Employee("刘备",'男',20000,25000,null));
        List<Employee> two = new ArrayList<>();
        two.add(new Employee("赵云",'男',30000,25000,null));
        two.add(new Employee("关羽",'男',45000,25000,"桀骜不驯"));
        two.add(new Employee("张飞",'男',40000,25000,"骂人"));
        two.add(new Employee("黄忠",'男',15000,25000,"养老金"));
        two.add(new Employee("马超",'男',25000,25000,null));
​
        //1.找出开发一部的最高工资。
//        Employee e =one.stream().max((e1,e2) ->Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
//                    .get();
//        System.out.println(e);
        Topperformer t =one.stream().max((e1,e2) ->Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
                .map(e -> new Topperformer(e.getName(), e.getSalary()+e.getBonus())).get();
        System.out.println(t);
        //2.统计平均工资,去掉最高工资和最低工资
        one.stream().sorted((e1,e2) -> Double.compare(e1.getSalary()+ e1.getBonus(), e2.getSalary()+ e2.getBonus()))
                .skip(1).limit(one.size()-2).forEach(e ->{
                    //求出总和,剩余员工的工资总和
                    allMoney +=(e.getSalary()+e.getBonus());
                });
        System.out.println("开发一部的平均工资是:"+ allMoney/(one.size()-2));
        //合并2个集合流,再统计。
        Stream<Employee> s1 = one.stream();
        Stream<Employee> s2 = two.stream();
        Stream<Employee> s3 = Stream.concat(s1,s2);
        s3.sorted((e1,e2) -> Double.compare(e1.getSalary()+ e1.getBonus(), e2.getSalary()+ e2.getBonus()))
                .skip(1).limit(one.size()+ two.size()-2).forEach(e ->{
                    //求出总和,剩余员工的工资总和
                    allMoney2 +=(e.getSalary()+e.getBonus());
                });
        System.out.println("开发部的平均工资是:"+ allMoney2/(one.size()+two.size() -2));
    }
}

11.Stream流的收集操作

        ①收集Stream流的含义:就是把Stream流操作后的结果数据转回到集合或者数组中去。

        ②Stream流:方便操作集合/数组的手段。

        ③Stream流的收集操作

 

④Collectors工具类提供了具体的收集方式

 

12.代码演示:

/** Stream流   简化集合和数组的API  结合了Lambda表达式  支持链式编程
 *Stream的获取 : Collection 默认stream()生成流
 * API
 * filter()  过滤流中数据
 * limit(long maxSize)  获取前几个元素
 * skip(long n)  跳过前几个元素
 * distinct()  去掉重复的元素
 * concat(Stream a,Stream b)  合并a和b两个流为一个流
 * compare  比较器
 * 收集Stream  :就是把Stream流操作后的数据转回到集合或者数组中去。
 * collect(Collector,collector)
 */
public class Stream_Demo7 {
    public static void main(String[] args) {
        
    // 收集Stream collect(Collector,collector)  :就是把Stream流操作后的数据转回到集合或者数组中去。
        List<String> ls = new ArrayList<>();
        ls.add("张无忌");
        ls.add("周芷若");
        ls.add("张三");
        ls.add("李四");
        ls.add("王五");
        Collections.addAll(ls,"张强","赵敏","张三丰");
        System.out.println(ls);
​
        Stream<String> s5 = ls.stream().filter(s ->s.startsWith("张"));
        List<String> zhangstream1 = s5.collect(Collectors.toList());
        System.out.println(zhangstream1);
​
        //注意: 流只能使用一次
        Stream<String> s4 = ls.stream().filter(s ->s.startsWith("张"));//再建一个流
        Set<String> zhangset = s4.collect(Collectors.toSet());
        System.out.println(zhangset);
​
        System.out.println("======================");
        Stream<String> s7 = ls.stream().filter(s ->s.startsWith("张"));
       String[] arrs = s7.toArray(String[]::new);//扩展,可以不用
        System.out.println("Arrays数组内容:"+Arrays.toString(arrs));
    }
}
;