参考总结: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