创建 Stream
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; import org.junit.Test; /* * 一、 Stream 的操作步骤 * * 1. 创建 Stream * 2. 中间操作 * 3. 终止操作 */ public class TestStreamAPI1 { /** * 创建 Stream */ @Test public void test1(){ //1. Collection 提供了两个方法 stream() 与 parallelStream() List<String> list = new ArrayList<>(); Stream<String> stream = list.stream(); // 获取一个顺序流 Stream<String> pstream = list.parallelStream(); // 获取一个并行流 //2. 通过 Arrays 中的 stream() 获取一个数组流 Integer[] nums = new Integer[10]; Stream<Integer> stream1 = Arrays.stream(nums); //3. 通过 Stream 类中静态方法 of() Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6); //4. 创建无限流 //迭代 Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2); stream3.limit(3).forEach(System.out::println); //生成 Stream<Double> stream4 = Stream.generate(Math::random); stream4.limit(3).forEach(System.out::println); } }
中间操作
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; import org.junit.Test; /** * 中间操作 */ public class TestStreamAPI2 { /** * 筛选与切片 * filter 从通道流中按自定义的规则过滤出满足条件的序列 * limit 截断流,使流中元素不超过指定数量 * skip 跳过流中指定个数的序列 * distinct 去除流中重复元素 */ @Test public void test1(){ List<Integer> list = Arrays.asList(2, 3, 5, 5, 5, 8, 11, 15); System.out.println("--------------------------filter"); // 所有的中间操作不会做任何的处理 Stream<Integer> stream = list.stream() .filter((i) -> { System.out.println("测试中间操作"); return i > 5; }); // 只有当做终止操作时,所有的中间操作会一次性的全部执行,称为“惰性求值” stream.forEach(System.out::println); System.out.println("--------------------------limit"); list.stream() .filter((i) -> { System.out.println("短路!"); // && || return i > 5; }).limit(1) .forEach(System.out::println); System.out.println("--------------------------skip"); list.stream() .filter((i) -> i > 5) .skip(2) .forEach(System.out::println); System.out.println("--------------------------distinct"); list.stream() .distinct() .forEach(System.out::println); } /** * 映射 * map 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 * flatMap 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 */ @Test public void test2() { List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee"); System.out.println("--------------------------map"); Stream<String> stream1 = strList.stream() .map(String::toUpperCase); stream1.forEach(System.out::println); System.out.println("--------------------------flatMap"); // map方式 Stream<Stream<Character>> stream2 = strList.stream() .map(TestStreamAPI2::filterCharacter); stream2.forEach((sm) -> { sm.forEach(System.out::println); }); // flatMap方式 Stream<Character> stream3 = strList.stream() .flatMap(TestStreamAPI2::filterCharacter); stream3.forEach(System.out::println); } private static Stream<Character> filterCharacter(String str){ List<Character> list = new ArrayList<>(); for (Character ch : str.toCharArray()) { list.add(ch); } return list.stream(); } /** * 排序 * sorted() 自然排序(Comparable) * sorted(Comparator com) 定制排序(Comparator) */ @Test public void Test3() { List<Character> strList = Arrays.asList('C', 'E', 'A', 'D', 'G', 'F', 'B'); System.out.println("--------------------------sorted自然排序"); strList.stream() .sorted() //.sorted(Collections.reverseOrder()) .forEach(System.out::println); System.out.println("--------------------------sorted定制排序"); strList.stream() .sorted((x, y) -> { if('D' <= x || 'D' <= y){ return x.compareTo(y); }else if('D' >= x || 'D' >= y){ return -Integer.compare(x, y); } return 0; }).forEach(System.out::println); } }
终止操作
public class Employee { private int id; private String name; private int age; private double salary; private Status status; public Employee() { } public Employee(int 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 Status getStatus() { return status; } public void setStatus(Status status) { this.status = status; } public int getId() { return id; } public void setId(int 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; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + ", status=" + status + "]"; } public enum Status { FREE, BUSY, VOCATION; } }
import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.DoubleSummaryStatistics; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.junit.Test; import com.example.demo.stream.Employee.Status; /** * 终止操作 */ public class TestStreamAPI3 { List<Employee> emps = Arrays.asList( new Employee(102, "李四", 59, 6666.66, Status.BUSY), new Employee(101, "张三", 18, 9999.99, Status.FREE), new Employee(103, "王五", 28, 3333.33, Status.VOCATION), new Employee(104, "赵六", 8, 7777.77, Status.BUSY), new Employee(104, "赵六", 8, 7777.77, Status.FREE), new Employee(104, "赵六", 8, 7777.77, Status.FREE), new Employee(105, "田七", 38, 5555.55, Status.BUSY) ); /** * 查找与匹配 * allMatch 检查是否匹配所有元素 * anyMatch 检查是否至少匹配一个元素 * noneMatch 检查是否没有匹配的元素 * findFirst 返回第一个元素 * findAny 返回当前流中的任意元素 * count 返回流中元素的总个数 * max 返回流中最大值 * min 返回流中最小值 */ @Test public void test1() { System.out.println("--------------------------allMatch"); boolean b1 = emps.stream() .allMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(b1); System.out.println("--------------------------anyMatch"); boolean b2 = emps.stream() .anyMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(b2); System.out.println("--------------------------noneMatch"); boolean b3 = emps.stream() .noneMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(b3); System.out.println("--------------------------findFirst"); Optional<Employee> op1 = emps.stream() .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())) .findFirst(); System.out.println(op1.get()); System.out.println("--------------------------findAny"); Optional<Employee> op2 = emps.parallelStream() .filter((e) -> e.getStatus().equals(Status.FREE)) .findAny(); System.out.println(op2.get()); System.out.println("--------------------------count"); long count = emps.stream() .filter((e) -> e.getStatus().equals(Status.FREE)) .count(); System.out.println(count); System.out.println("--------------------------max"); Optional<Double> op3 = emps.stream() .map(Employee::getSalary) .max(Double::compare); System.out.println(op3.get()); System.out.println("--------------------------min"); Optional<Employee> op4 = emps.stream() .min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())); System.out.println(op4.get()); } /** * 归约 * reduce(T identity, BinaryOperator) 可以将流中元素反复结合起来,得到一个值,返回 T * reduce(BinaryOperator) 可以将流中元素反复结合起来,得到一个值,返回 Optional<T> */ @Test public void test2() { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Integer sum = list.stream() .reduce(0, (x, y) -> x + y); System.out.println(sum); System.out.println("--------------------------"); Optional<Integer> op = list.stream() .reduce(Integer::sum); System.out.println(op.get()); } /** * 收集 * collect 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总方法 * * Collectors类方法 * toList List<T> 把流中元素收集到List * toSet Set<T> 把流中元素收集到Set * toCollection Collection<T> 把流中元素收集到创建的集合 */ @Test public void test3() { System.out.println("--------------------------list"); List<String> list = emps.stream() .map(Employee::getName) .collect(Collectors.toList()); list.forEach(System.out::println); System.out.println("--------------------------set"); Set<String> set = emps.stream() .map(Employee::getName) .collect(Collectors.toSet()); set.forEach(System.out::println); System.out.println("--------------------------collection"); Collection<String> collection = emps.stream() .map(Employee::getName) .collect(Collectors.toCollection(ArrayList::new)); collection.forEach(System.out::println); } /** * Collectors类方法 * counting Long 计算流中元素的个数 * summingInt Integer 对流中项目的一个整数属性求和 * averagingInt Double 计算流中项目 Integer 属性的平均值 * maxBy Optional<T> 根据比较器选择最大值 * minBy Optional<T> 根据比较器选择最小值 * summarizingInt IntSummaryStatistics 收集关于流中项目 Integer 属性的统计值,例如最大、最小、总和与平均值 */ @Test public void test4() { System.out.println("--------------------------count"); Long count = emps.stream() .collect(Collectors.counting()); System.out.println(count); System.out.println("--------------------------sum"); Double sum = emps.stream() .collect((Collectors.summingDouble(Employee::getSalary))); System.out.println(sum); System.out.println("--------------------------avg"); Double avg = emps.stream() .collect((Collectors.averagingDouble(Employee::getSalary))); System.out.println(avg); System.out.println("--------------------------max"); Optional<Employee> max = emps.stream() .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(),e2.getSalary()))); System.out.println(max); System.out.println("--------------------------mix"); Optional<Double> mix = emps.stream() .map(Employee::getSalary) .collect(Collectors.minBy(Double::compare)); System.out.println(mix.get()); System.out.println("--------------------------statistics"); DoubleSummaryStatistics dss = emps.stream() .collect(Collectors.summarizingDouble(Employee::getSalary)); System.out.println(dss.getMax() + "--" + dss.getMin() + "--" + dss.getCount()); } /** * Collectors类方法 * joining String 连接流中每个字符串 */ @Test public void test5() { System.out.println("--------------------------join"); String join = emps.stream() .map(Employee::getName) .collect(Collectors.joining("," , "----", "----")); System.out.println(join); } /** * Collectors类方法 * groupingBy Map<K, List<T>> 根据某属性值对流分组,属性为K,结果为V */ @Test public void test6() { System.out.println("--------------------------group"); Map<Status, List<Employee>> group = emps.stream() .collect(Collectors.groupingBy(Employee::getStatus)); System.out.println(group); System.out.println("--------------------------multistage group"); Map<Status, Map<String, List<Employee>>> mgroup = emps.stream() .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> { if(e.getAge() >= 60) return "老年"; else if(e.getAge() >= 35) return "中年"; else return "成年"; }))); System.out.println(mgroup); } /** * Collectors类方法 * partitioningBy Map<Boolean, List<T>> 根据true或false进行分区 */ @Test public void test7() { System.out.println("--------------------------partition"); Map<Boolean, List<Employee>> partition = emps.stream() .collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000)); System.out.println(partition); } }