2、JDK新语法之Stream
Stream是数据渠道,用于操作集合、数组等。集合讲的是数据,Stream讲的是计算,即Stream是对集合的一系列操作过程。
注意:
1、Stream不会自己存储元素
2、Stream不会改变源对象,它会返回一个持有操作结果的新Stream
3、Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行
Employee实体类,后面会用到
package com.lee.jdk.Entity;import java.util.Objects;
public class Employee {
private Integer id;
private String name;
private int age;
private Double salary;
private Status status;
public Employee() {
}
public Employee(Integer id) {
this.id = id;
}
public Employee(Integer id, String name) {
this.id = id;
this.name = name;
}
public Employee(Integer id, String name, int age, Double salary, Status status) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.status = status;
}
public Employee(Integer id, String name, int age, Double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public enum Status{
FREE,BUSY,VACATION
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name="" + name + """ +
", age=" + age +
", salary=" + salary +
", status=" + status +
"}";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return age == employee.age &&
Objects.equals(id, employee.id) &&
Objects.equals(name, employee.name) &&
Objects.equals(salary, employee.salary);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age, salary);
}
}
Stream语法规则 一
package com.lee.jdk.stream;import com.lee.jdk.Entity.Employee;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
/**
* 一、Stream的三个操作步骤:
* 1、创建Stream
* 2、中间操作
* 3、终止操作
*
* 二、创建Stream
* 1、Collection
* 2、Arrays
* 3、Stream的of
* 4、Stream的Iterate和Generate创建无限流
*
* 三、中间操作
* 1、筛选 和 切片
* filter : 接受lambda,并排除某些元素
* limit : 截断流,使其元素不超过给定数量
* skip(n) : 跳过元素,返回一个扔掉了前N个元素的流。若流中元素不足N个,则返回一个空流。
* distinct : 筛选,通过流生成元素的hashCode和equals去除重复元素
* 2、映射
* map:会将集合中的数据,一个个的应用于map的函数上
* flatMap : 会将集合中的数据,一个个的应用于map的函数上.并且将流中的每一个值换成另一个流,然后把所有流连成一个流
*
* 3、排序
* sorted 自然排序
* sorted(Comparator comp) 自定义排序
*/
public class TestStreamApi1 {
List<Employee> employeeList = Arrays.asList(
new Employee(1,"张三",25,17000d),
new Employee(2,"李四",18,19000d),
new Employee(3,"王五",55,7000d),
new Employee(4,"赵六",39,12000d),
new Employee(5,"刘七",28,14000d),
new Employee(5,"刘七",28,14000d),
new Employee(5,"刘七",28,14000d)
);
//1、四种创建Stream的方式
@Test
public void test1(){
//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方法创建无限流
Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
Stream<Double> stream5 = Stream.generate(() -> Math.random() * 100);
}
//2、中间操作--filter
@Test
public void test2(){
//中间操作,不会执行任何操作---集合会在stream内部循环
Stream<Employee> stream = employeeList.stream()
.filter((e) -> {
System.out.println("中间操作,不会执行任何操作");
return e.getAge() > 35;
});
//终止操作:一次性执行全部内容,即 "惰性求值"
stream.forEach(System.out::println);
}
//3、中间操作--limit
@Test
public void test3(){
//中间操作,不会执行任何操作
Stream<Employee> stream = employeeList.stream()
.filter((e) -> {
System.out.println("中间操作,limit");
return e.getSalary()>8000;
})
.limit(2);//查找到Limit限定的值后,集合就中断不再继续执行了。这就是"短路"
//终止操作:一次性执行全部内容,即 "惰性求值"
stream.forEach(System.out::println);
}
//4、中间操作--skip
@Test
public void test4(){
//中间操作,不会执行任何操作
Stream<Employee> stream = employeeList.stream()
.filter((e) -> e.getSalary()>8000)
.skip(2);//跳过前两个
//终止操作:一次性执行全部内容,即 "惰性求值"
stream.forEach(System.out::println);
}
//5、中间操作--distinct
@Test
public void test5(){
//中间操作,不会执行任何操作
Stream<Employee> stream = employeeList.stream()
.filter((e) -> e.getSalary()>8000)
.distinct();//去重必须重写Employee的hashcode和equals方法
//终止操作:一次性执行全部内容,即 "惰性求值"
stream.forEach(System.out::println);
}
//6、map:会将集合中的数据,一个个的应用于map的函数上
@Test
public void test6(){
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
list.stream()
.map((s)->s.toUpperCase())
.forEach(System.out::println);
System.out.println("===========================");
employeeList.stream()
.map((e)->e.getName()+"- ")
.distinct()
.forEach(System.out::print);
}
//7、flatmap : 会将集合中的数据,一个个的应用于map的函数上.并且将流中的每一个值换成另一个流,然后把所有流连成一个流
@Test
public void test7(){
List<String> list = Arrays.asList("aaa","bbb","ccc");
//map---类似于list中的add
Stream<Stream<Character>> mapStream = list.stream()
.map(TestStreamApi1::filterCharacter);
mapStream.forEach((sm)->sm.forEach(System.out::println));
System.out.println("===============================");
//flatMap---类似于list中的addAll
Stream<Character> flatMapStream = list.stream()
.flatMap(TestStreamApi1::filterCharacter);
flatMapStream.forEach(System.out::println);
}
public static Stream<Character> filterCharacter(String s){
List<Character> list = new ArrayList<>();
for(Character c : s.toCharArray()){
list.add(c);
}
return list.stream();
}
//1、排序
@Test
public void test8(){
List<String> list = Arrays.asList("ccc","eee","ddd","bbb","aaa");
list.stream()
.sorted()
.forEach(System.out::println);
System.out.println("-----------------------------");
employeeList.stream()
.sorted((e1,e2)->{
if(Objects.equals(e1.getAge(),e2.getAge())){
return -e1.getSalary().compareTo(e2.getSalary());
}else{
return Integer.compare(e1.getAge(),e2.getAge());
}
})
.forEach(System.out::println);
}
}
Stream语法规则 二
package com.lee.jdk.stream;import com.lee.jdk.Entity.Employee;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 终止操作
* 1、查找与匹配
* AllMatch 检查是否全部匹配
* anyMatch 检查是否至少匹配一个元素
* noneMatch 检查是否全部没匹配
*
* findFirst 返回第一个元素
* findAny 返回任意元素
* count 返回流中元素总个数
* max 返回流中最大值
* min 返回流中最小值
*
* 2、规约
* reduce 将流中元素反复结合起来,得到一个值
* 3、收集
* collect 将结果放入集合中
*/
public class TestStreamApi2 {
List<Employee> employeeList = Arrays.asList(
new Employee(1,"张三",25,17000d, Employee.Status.BUSY),
new Employee(2,"李四",18,19000d, Employee.Status.VACATION),
new Employee(3,"王五",55,7000d, Employee.Status.FREE),
new Employee(4,"赵六",39,12000d, Employee.Status.BUSY),
new Employee(5,"刘七",28,14000d, Employee.Status.FREE),
new Employee(6,"刘七",28,15000d, Employee.Status.VACATION),
new Employee(7,"刘七",28,16000d, Employee.Status.BUSY)
);
//1、查找与匹配
@Test
public void test(){
//allMatch
boolean b = employeeList.stream()
.allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b);
System.out.println("--------------------------");
//anyMatch
boolean b1 = employeeList.stream()
.anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b1);
System.out.println("---------------------------");
//noneMatch
boolean b2 = employeeList.stream()
.noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b2);
System.out.println("----------------------------");
//findFirst
Optional<Employee> op1 = employeeList.stream()
.sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
.findFirst();
System.out.println(op1.get());
System.out.println("----------------------------");
//findAny
Optional<Employee> op2 = employeeList.stream()
.filter((e)->e.getStatus().equals(Employee.Status.BUSY))
.findAny();
System.out.println(op2.get());
Optional<Employee> op3 = employeeList.parallelStream()
.filter((e)->e.getStatus().equals(Employee.Status.BUSY))
.findAny();
System.out.println(op3.get());
System.out.println("----------------------------");
//count
long count = employeeList.stream()
.count();
System.out.println(count);
System.out.println("---------------------------");
//max
Optional<Integer> op4 = employeeList.stream()
.map(Employee::getAge)
.max((e1, e2) -> Integer.compare(e1, e2));
System.out.println(op4.get());
System.out.println("---------------------------");
//min
Optional<Integer> op5 = employeeList.stream()
.map(Employee::getAge)
.min((e1, e2) -> Integer.compare(e1, e2));
System.out.println(op5.get());
}
//2、规约:reduce 将流中元素反复结合起来得到一个值
@Test
public void test2(){
//将1-10中所有数相加
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer num = list.stream()
.reduce(0, (x, y) -> x + y);
System.out.println(num);
System.out.println("-----------------------------");
//所有人工资总和
Optional<Double> op1 = employeeList.stream()
.map(Employee::getSalary)
.reduce(Double::sum);
System.out.println(op1.get());
}
//3、收集
@Test
public void test3(){
//收集所有人的姓名
List<String> list = employeeList.stream()
.map(Employee::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println("==============================");
//收集BUSY状态的员工
List<Employee> list2 = employeeList.stream()
.filter((e) -> e.getStatus().equals(Employee.Status.BUSY))
.collect(Collectors.toList());
list2.forEach(System.out::println);
//总数
Long count = employeeList.stream()
.collect(Collectors.counting());
System.out.println(count);
System.out.println("================================");
//总和
Double sum = employeeList.stream()
.collect(Collectors.summingDouble((e) -> e.getSalary()));
System.out.println(sum);
System.out.println("================================");
//平均值
Double avg = employeeList.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(avg);
//等等
}
}
以上是 2、JDK新语法之Stream 的全部内容, 来源链接: utcz.com/z/511985.html