首页 > 编程语言 >Java8中stream新特性

Java8中stream新特性

时间:2022-09-23 12:45:36浏览次数:88  
标签:Stream stream 特性 public println Employee new Java8

参考总结:https://www.bilibili.com/video/BV1ut411g7E9?p=7&vd_source=c85b4a015a69e82ad4f202bd9b87697f

了解Stream

java8中有两大最为重要的改变。第一个是Lambda表达式;另一个是Stream API(java.util.stream.*)

Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找,过滤和映射数据等操作。使用Stream API对集合数据进行操作,就类似使用SQL执行的数据库查询。也可以使用Stream API 来并行执行操作。简而言之,Stream API提供了一种高效且易于使用的处理数据的方式

流是什么?

是数据渠道,用于操作数据源(集合,数组等)所生成的元素序列。“集合讲的是数据,流讲的是计算”

注意:

1.stream自己不会存储数据

2.stream不会改变源对象。相反,他们会返回一个持有结果的新Stream

3.stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行。

 

 创建Stream

package test01;

import org.junit.Test;
import java.util.*;
import java.util.stream.Stream;
public class test {

    //创建Stream
    @Test
    public void test(){
        //1. 可以通过Collection系列集合提供的stream()或parallelStream()
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();

        //2. 通过Arrays中的静态方法stream()获取数组流
        Employee[] emps = new Employee[10];
        Stream<Employee> stream2 = Arrays.stream(emps);

        //3. 通过Stream类中的静态方法of()
        Stream<String> stream3 = Stream.of("aa","bb","cc");

        //4.创建无限流
        //迭代,
        Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);
        stream4.forEach(System.out::println);//无限打印偶数
        //生成
        Stream.generate(() -> Math.random())
                .limit(5)
                .forEach(System.out::println);
    }

}

stream常见的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性的全部处理,称为“惰性求值”。

筛选与切片

filter(Predicate p)---接收Lambda,从流中排除某些元素

limit(long maxSize)---截断流,使其元素不超过给定数量

skip(long n)---跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补

distinct()---筛选,通过流所产生元素的hashCode()和equals()去除重复元素

 实体类

package test01;

import java.util.Objects;

public class Employee {

    private String name;

    private Integer age;

    private double salary;

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

    public Employee() {
    }

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

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

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


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

    @Override
    public int hashCode() {
        return Objects.hash(name, age, salary);
    }
}
package test01;
import org.junit.Test;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;

public class test {
    List<Employee> employees = Arrays.asList(
            new Employee("张三",18, 4444.44),
            new Employee("李四",58, 3333.33),
            new Employee("王五",26, 6666.66),
            new Employee("赵六",36, 5555.55),
            new Employee("田七",12, 8888.88),
            new Employee("田七",12, 8888.88),
            new Employee("田七",12, 8888.88)
    );
    //内部迭代:迭代操作由Stream API完成
    @Test
    public void test1(){
        //中间操作:不会执行任何操作
        Stream<Employee> stream = employees.stream()
                                    .filter((e) -> {
                                        System.out.println("Stream API的中间操作");
                                        return e.getAge() > 35;
                                    });
        //终止操作:一次性执行全部内容,即“惰性求值”
        stream.forEach(System.out::println);
    }
    //外部迭代
    @Test
    public void test2(){
        Iterator<Employee> it = employees.iterator();

        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
    @Test
    public void test3(){
        employees.stream()
                .filter((e) -> {
                    System.out.println("短路!");//满足条件后,后续操作就不再执行,提高效率,类似&& ||
                    return e.getSalary() > 5000;
                })
                .limit(2)
                .forEach(System.out::println);
    }
    @Test
    public void test4(){
        employees.stream()
                .filter((e) -> e.getSalary() >5000)
                .skip(2)
                .distinct() //重写hashcode()和equals()
                .forEach(System.out::println);
    }
}

映射

map--接收Lambda,将元素转换成其他形式或者提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素,

flatMap--接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

package test01;
import org.junit.Test;

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

public class test {
    List<Employee> employees = Arrays.asList(
            new Employee("张三",18, 4444.44),
            new Employee("李四",58, 3333.33),
            new Employee("王五",26, 6666.66),
            new Employee("赵六",36, 5555.55),
            new Employee("田七",12, 8888.88),
            new Employee("田七",12, 8888.88),
            new Employee("田七",12, 8888.88)
    );
    /*
    * 映射
    * map--接收Lambda,将元素转换成其他形式或者提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
    * flatMap--接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
    * */
    @Test
    public void test(){
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");

        list.stream()
                .map((str) -> str.toUpperCase())
                .forEach(System.out::println);

        System.out.println("------------------------------------------------");
        employees.stream()
                .map(Employee::getName)
                .forEach(System.out::println);
        System.out.println("------------------------------------------------");
//        //流中套流,理解很麻烦
//        Stream<Stream<Character>> stream = list.stream()
//                .map(test::filterCharacter);{{a,a,a},{b,b,b}....}
//
//        stream.forEach((sm) -> {
//            sm.forEach(System.out::println);
//        });
        System.out.println("------------------------------------------------");
        Stream<Character> sm = list.stream()
                .flatMap(test::filterCharacter);//{a,a,a,b,b,b....}
        sm.forEach(System.out::println);

    }
    @Test
    public void test2(){
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");

        List list2 = new ArrayList();

        list2.add(11);
        list2.add(22);
//        list2.add(list); //[11, 22, [aaa, bbb, ccc, ddd, eee]]
        list2.addAll(list); //[11, 22, aaa, bbb, ccc, ddd, eee]

        System.out.println(list2);


    }
    public static Stream<Character> filterCharacter(String str){//类似add(Object obj) addAll(Collection coll)
        List<Character> list = new ArrayList<>();

        for(Character ch : str.toCharArray()){
            list.add(ch);
        }

        return list.stream();
    }
}

stream_排序

sorted()---自然排序

sorted(Comparator com)---定制排序

 

allMatch---检查是否匹配所有元素

anyMatch---检查是否至少匹配一个元素

noneMatch---检查是否没有匹配所有元素

findFirst---返回第一个元素

findAny---返回当前流中的任意元素

count---返回流中元素的总个数

max---返回流中最大值

min---返回流中最小值

package test01;

import org.junit.Test;
import java.util.*;

public class test {
    List<Employee> employees = Arrays.asList(
            new Employee("张三",18, 4444.44),
            new Employee("李四",58, 3333.33),
            new Employee("王五",26, 6666.66),
            new Employee("赵六",36, 5555.55),
            new Employee("田七",12, 8888.88),
            new Employee("田七",12, 8888.88),
            new Employee("田七",12, 8888.88)
    );
    /*
    * sorted()---自然排序(Comparable)
    * sorted(Comparator com)---定制排序(Comparator)
    * */
    @Test
    public void test(){
        List<String> list = Arrays.asList("ccc", "aaa", "bbb", "ddd", "eee");

        list.stream()
                .sorted()//自然排序
                .forEach(System.out::println);//"aaa", "bbb", "ccc", "ddd", "eee"

        System.out.println("------------------------------------------------");
        employees.stream()
                .sorted((e1,e2) -> {
                    if(e1.getAge().equals(e2.getAge())){
                        return e1.getName().compareTo(e2.getName());
                    }else{
                        return -e1.getAge().compareTo(e2.getAge());
                    }
                }).forEach(System.out::println);
        /*
        * Employee{name='李四', age=58, salary=3333.33}
          Employee{name='赵六', age=36, salary=5555.55}
          Employee{name='王五', age=26, salary=6666.66}
          Employee{name='张三', age=18, salary=4444.44}
          Employee{name='田七', age=12, salary=8888.88}
          Employee{name='田七', age=12, salary=8888.88}
          Employee{name='田七', age=12, salary=8888.88}
        * */
    }
}

Stream终止操作

终止操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List,Integer,甚至是void

查找与匹配

方法 描述
allMatch(predicate p) 检查是否匹配所有元素
anyMatch(Predicate p) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查流里是否没有元素能够匹配指定的规则
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素

 

 

 

 

 

package test01;

import org.junit.Test;
import java.util.*;

public class test {
    List<Employee> employees = Arrays.asList(
            new Employee("张三",18, 4444.44, Employee.Status.FREE),
            new Employee("李四",58, 3333.33, Employee.Status.BUSY),
            new Employee("王五",26, 6666.66, Employee.Status.VOCATION),
            new Employee("赵六",36, 5555.55, Employee.Status.FREE),
            new Employee("田七",12, 8888.88, Employee.Status.BUSY)
    );
    @Test
    public void test1(){
        boolean b1 = employees.stream()
                .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);// false

        boolean b2 = employees.stream()
                .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b2);// true

        boolean b3 = employees.stream()
                .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b3);// false

        Optional<Employee> op = employees.stream()
                .sorted((e1,e2) -> Double.compare(e1.getSalary(), e2.getSalary())) //工资最低的
                .findFirst();

        System.out.println(op.get()); //Employee{name='李四', age=58, salary=3333.33, Status=BUSY}

        Optional<Employee> op2 = employees.parallelStream()//并行流
                .filter((e) -> e.getStatus().equals(Employee.Status.FREE))
                .findAny();

        System.out.println(op2.get());

    }
    @Test
    public void test2(){
        Long count = employees.stream()
                .count();
        System.out.println(count);

        Optional<Employee> op1 = employees.stream()
                .max((e1,e2) -> Double.compare(e1.getSalary(), e2.getSalary()));//工资最高
        System.out.println(op1.get());

        Optional<Double> op2 = employees.stream()
                .map(Employee::getSalary)
                .min(Double::compare);//最小工资数
        System.out.println(op2.get());
    }
}

 

标签:Stream,stream,特性,public,println,Employee,new,Java8
From: https://www.cnblogs.com/jinci2022/p/16721734.html

相关文章