Java Stream 使用

Stream流的使用

使用的操作类:

Employee

package useData;

import java.util.Objects;

public class Employee {
    private int id;
    private String name;
    private int age;
    private double salary;

    public Employee(int id, String name, int age, double salary) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return id == employee.id &&
                age == employee.age &&
                Double.compare(employee.salary, salary) == 0 &&
                name.equals(employee.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age, salary);
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }

    public void setId(int id) {
        this.id = id;
    }

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

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

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

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public double getSalary() {
        return salary;
    }
}

EmployeeData

package useData;

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

public class EmployeeData {
    public static List<Employee> getEmployees(){
        List<Employee> list = new ArrayList<>();

        list.add(new Employee(1001, "马化腾", 34, 6000.38));
        list.add(new Employee(1002, "马云", 30, 6020.38));
        list.add(new Employee(1003, "刘强东", 29, 6300.38));
        list.add(new Employee(1004, "雷军", 35, 7000.32));
        list.add(new Employee(1005, "李彦宏", 32, 6000.38));
        list.add(new Employee(1006, "比尔盖茨", 34, 9000.38));
        list.add(new Employee(1007, "任正非", 21, 8000.38));
        list.add(new Employee(1008, "扎克伯格", 49, 7000.38));

        return list;
    }
}

一、进行筛选与切片

package day12;

import org.junit.Test;
import useData.Employee;
import useData.EmployeeData;

import java.util.List;
import java.util.stream.Stream;
/*
筛选与切片
filter
limit
skip
distinct
 */
public class StreamAPITest1 {
    @Test
    public void test1(){
        List<Employee> list = EmployeeData.getEmployees();
        // 1. filter(Preficate p) - 接收 Lambda, 从六种排出某些元素
        Stream<Employee> stream = list.stream();
        // 练习查询 员工表中 大于 7000 的
        stream.filter(e->e.getSalary()>7000).forEach(System.out::println);
        System.out.println("---------------------------------------------------");
        // 2. limit(n) - 截断流 , 使其元素不能超过给定量
        // 注意这样用是错的 已经执行终止操作 需要重新给定源
//        stream.limit(3).forEach();
        list.stream().limit(3).forEach(System.out::println);
        System.out.println("---------------------------------------------------");
        // 3. skip(n) 跳过前 n 条数据
        list.stream().skip(3).forEach(s-> System.out.println(s));

        System.out.println("---------------------------------------------------");
        // distincet() -筛选 通过流所生成的元素的hashcode() 和 equals() 取出重复元素
        list.add(new Employee(1003, "刘强东", 29, 6300.38));
        list.add(new Employee(1003, "刘强东", 29, 6300.38));
        list.add(new Employee(1003, "刘强东", 29, 6300.38));
        System.out.println("去重前:");
        for(Employee e: list)
            System.out.println(e);

        System.out.println("去重后:");
        list.stream().distinct().forEach(System.out::println);

    }
}

二、映射操作

package day12;

import org.junit.Test;
import useData.Employee;
import useData.EmployeeData;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/*
映射
map
flatMap
 */
public class StreamAPITest2 {
   @Test
    public void test2(){
       // map(function f) 接收一个函数作为参数 ,将元素转换成其他形式或者提取信息, 该函数会被应用到每个元素上, 并将其映射成一个新的元素
       List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
       list.stream().map(s->s.toUpperCase()).forEach(s-> System.out.println(s));
       System.out.println("--------------------------------------------------------");
       // 练习:获取员工姓名长度大于3的员工的姓名
       List<Employee> employees = EmployeeData.getEmployees();
       employees.stream().map(s->s.getName()).filter(s->s.length()>3).forEach(s-> System.out.println(s));
//       employees.stream().map(Employee::getName).filter().forEach(s-> System.out.println(s));
       // 可以看出 map 调用后 其中仍有stream中的 stream
       Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest2::fromStringToStream);
       streamStream.forEach(s->{
           s.forEach(System.out::println);
       });
       System.out.println("--------------------------------------------------------");
       // flat(Mapfunction f) 接收一个函数作为参数, 将流中的 每个值 换成 另一个流, 然后把所有流 连接成 一个 流
       // 注意看 test3 的类比 map 相当于 list1.add()   而 flatMap 相当于 list1.addAll() 方法
       Stream<Character> characterStream = list.stream().flatMap(StreamAPITest2::fromStringToStream);
       characterStream.forEach(System.out::println);
   }
   @Test
    public void test3(){
       ArrayList list1 = new ArrayList();
       list1.add(1);
       list1.add(2);
       list1.add(3);

       ArrayList list2 = new ArrayList();
       list2.add(4);
       list2.add(5);
       list2.add(6);
//       list1.add(list2); // [1, 2, 3, [4, 5, 6]]
       list1.addAll(list2);  // [1, 2, 3, 4, 5, 6]
       System.out.println(list1);
   }

   // 把字符串 转成对于有的 stream 的集合
   public static Stream<Character> fromStringToStream(String str){
       ArrayList<Character> list = new ArrayList<>();
       for(Character c : str.toCharArray()){
           list.add(c);
       }
       return list.stream();
   }
}

三、排序操作

package day12;

import org.junit.Test;
import useData.Employee;
import useData.EmployeeData;

import java.util.Arrays;
import java.util.List;

/*
排序
sorted
 */
public class StreamAPITest3 {
    @Test
    public void test4(){
        // 排序的用法
//        sorted : 产生一个新流, 其中按自然顺序排序
        List<Integer> list = Arrays.asList(4, 1, 2, 6, 3, 0, -34);
        list.stream().sorted().forEach(System.out::println);
        System.out.println("------------------------------------------------");
        List<Employee> employees = EmployeeData.getEmployees();
//        employees.stream().sorted().forEach(System.out::println);  // 由于 Employee 没有去实现 comparable 接口 所以不能直接用
//        sorted(Comparator com) 产生一个新流, 其中按比较顺序排序
        employees.stream().sorted(
//                (e1,e2)->{
//            return e1.getAge() - e2.getAge();
//    }
            // 或者
                (e1,e2)-> e1.getAge()-e2.getAge()
        ).forEach(System.out::println);
    }
}

四、终止操作

package day12;

import org.junit.Test;
import useData.Employee;
import useData.EmployeeData;

import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * 终止操作
 * foreach 内部迭代
 * 还有 匹配与查找
 * allMatch(Predicate p)  : 检查是否匹配所有元素
 * anyMatch(Predicate p)  : 检查
 * noneMatch(Predicate p)
 * findFirst()
 * findAny()
 */
public class StreamAPITest4 {
    // 1- 匹配与查找
    @Test
    public void test1(){
//        allMatch(Predicate p)  : 检查是否匹配所有元素
        // 练习 是否所有员工年龄都大于35
        List<Employee> employees = EmployeeData.getEmployees();
        // allMatch 返回值是个 boolean 类型
        boolean allMatch = employees.stream().allMatch(e -> e.getAge() > 35);
        System.out.println(allMatch);  // 判断是否都大于 35 返回false 说明有小于35的

        // anyMatch(Predicate p)  :是否有大于 指定 指定元素的
        boolean anyMatch = employees.stream().anyMatch(e -> e.getSalary() < 9000);
        System.out.println(anyMatch);

//        noneMatch(Predicate p) : 检查是否没有匹配的元素
        // 检查是否有姓雷的
        boolean noneMatch = employees.stream().noneMatch(s -> s.getName().startsWith("雷"));
        System.out.println("是否有没有姓雷的:"+noneMatch);  // 雷军 姓雷 所有会返回 false

//        findFirst()  : 返回匹配到的第一个元素 / 返回流中的第一个元素
        Optional<Employee> first = employees.stream().findFirst();
        System.out.println("返回流中的第一个元素:"+first);
//        findAny : 返回当前流中的任意一个元素
        Optional<Employee> first1 = employees.parallelStream().findAny();
        System.out.println("返回并行流中的第一个元素:"+first1);

    }

    @Test
    public void test2(){
        List<Employee> employees = EmployeeData.getEmployees();
        // count - 返回流中元素的个数
        // 默认是long 防止返回的值太大
        long count = employees.stream().filter(e -> e.getSalary() > 7000).count();
        System.out.println(count);
        // max(Comparator c) - 返回流中最大值
        // 对于数值型 可能好判断 不过对于 其他类型则还是需要比较器的
        Optional<Employee> max = employees.stream().max((e1, e2) -> {
            return Double.compare(e1.getSalary(), e2.getSalary());
        });
        System.out.println("薪水最多的: "+ max);
        // 或者这样写
        Stream<Double> doubleStream = employees.stream().map(e -> e.getSalary());
        Optional<Double> max1 = doubleStream.max(Double::compare);
        System.out.println("2薪水最多的:"+max1);


        // min(Comparator c) - 返回流中最小值
        // 使用同上
    }

}

五、归约操作

package day12;

import org.junit.Test;
import useData.Employee;
import useData.EmployeeData;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 归约
 * reduce(T identity, BinaryOperator) - 可以将流中的元素进行反复结合,得到一个值。
 * // 练习1: 计算 1-10中的自然和
 */
public class StreamAPITest5 {
    @Test
    public void test1(){
        // int 数组 转换成 列表
        int[] arr = {1,2,3};
        List<int[]> ints = Arrays.asList(arr);
        System.out.println(ints);   // [[I@46ee7fe8]
        Stream<Integer> boxed = Arrays.stream(arr).boxed();
        List<Integer> collect = boxed.collect(Collectors.toList());
//        Arrays.stream(arr).collect(Collectors.toList());
        System.out.println(collect); // [1, 2, 3]

//        Arrays.stream(arr).flatMap(s->(int)s)


    }
    @Test
    public void test2(){
//        educe(T identity, BinaryOperator) - 可以将流中的元素进行反复结合,得到一个值。
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer reduce = list.stream().reduce(0, Integer::sum);// 0表示初始值 sum 表示累加操作
        System.out.println(reduce);
        // 计算所有员工工资的总和
        List<Employee> employees = EmployeeData.getEmployees();
        Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());
        Double doubleSum = salaryStream.reduce(0.0, Double::sum);  // 下面一种写法也是可以的
        System.out.println("薪资总和: "+doubleSum);
        Optional<Double> sumMoney = employees.stream().map(e -> e.getSalary()).reduce((d1, d2)-> d1+d2); // 自己求 不使用 sum
        System.out.println("薪资总和: "+sumMoney);
        Optional<Double> sumMoney2 = employees.stream().map(e -> e.getSalary()).reduce(Double::sum); // 自己求 不使用 sum
        System.out.println("薪资总和: "+sumMoney2);

    }
}

六、收集操作

package day12;

import org.junit.Test;
import useData.Employee;
import useData.EmployeeData;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 收集操作 :
 * collect(Collector c)    : 将流转换为其他形式。 接收一个 Collector 接口的实现, 用于给 Stream 中的元素汇总的方法
 * Collector 接口中的方法的实现决定了如何对流执行收集的操作(如 收集到 List、Set、Map)
 */
public class StreamAPITest6 {
    @Test
    public void test1(){
        // 查找工资大于 7000的员工, 结果返回一个 List 或者 Set
        List<Employee> employees = EmployeeData.getEmployees();
        List<Employee> list = employees.stream().filter(s -> s.getSalary() > 7000).collect(Collectors.toList());
        list.forEach(System.out::println);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值