SteamAPI
文章目錄
- 1 stream的創建
- 1.1 通過Collection stream() 與 parallelStream()
- 1.2 通過 Arrays 中的 靜態方法stream() 獲取一個數組流
- 1.3 通過 Stream 類中靜態方法 of()
- 1.4 創建無限流(無窮)
- 2 stream的中間操作
- 2.1 篩選與切片
- 2.1.1 filter:接收 Lambda , 從流中過濾某些元素。
- 2.1.2 limit: 截斷流,使其元素不超過給定數量。
- 2.1.3 skip(n) :跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足 n 個,則返回一個空流。與 limit(n) 互補
- 2.1.4 distinct:去重 必須重寫hashCode() 和 equals() (可以生成)才能去重
- 2.2 映射
- 2.2.1 map 接收lamda
- 2.2.2 flatMap 把多個流歸總成一個流
- 2.2.3 reduce
- 2.2.4 collect
- 3 終止操作
- 3.1 各種查找的方法
- 4 并行流與串行流
1 stream的創建
1.1 通過Collection stream() 與 parallelStream()
List<String> list = new ArrayList<>(); Stream<String> stream = list.stream(); //獲取一個順序流 Stream<String> parallelStream = list.parallelStream(); //獲取一個并行流1.2 通過 Arrays 中的 靜態方法stream() 獲取一個數組流
Integer[] nums = new Integer[10]; Stream<Integer> stream1 = Arrays.stream(nums);1.3 通過 Stream 類中靜態方法 of()
Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6);1.4 創建無限流(無窮)
流無窮無盡,一直產生,這里用了limit,就不會無限了
//迭代 Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2).limit(10); stream3.forEach(System.out::println); //生成 Stream<Double> stream4 = Stream.generate(Math::random).limit(2); stream4.forEach(System.out::println);2 stream的中間操作
List<Employee> emps = Arrays.asList(new Employee(102, "李四", 59, 6666.66),new Employee(101, "張三", 18, 9999.99),new Employee(103, "王五", 28, 3333.33),new Employee(104, "趙六", 8, 7777.77),new Employee(104, "趙六", 8, 7777.77),new Employee(104, "趙六", 8, 7777.77),new Employee(105, "田七", 38, 5555.55));2.1 篩選與切片
2.1.1 filter:接收 Lambda , 從流中過濾某些元素。
//所有的中間操作不會做任何的處理Stream<Employee> stream = emps.stream().filter((e) -> {System.out.println("測試中間操作");//先輸出了這個return e.getAge() <= 35;//再過濾這個});//只有當做終止操作時,中間操作才會執行,稱為“惰性求值”stream.forEach(System.out::println);效果
2.1.2 limit: 截斷流,使其元素不超過給定數量。
短路(找到滿足條件的數據且數量達到給定的就不再找了)
emps.stream().filter((e) -> {System.out.println("短路!"); // && ||return e.getSalary() >= 5000;}).limit(4).forEach(System.out::println);效果
2.1.3 skip(n) :跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足 n 個,則返回一個空流。與 limit(n) 互補
//扔掉 最先找到的2個emps.parallelStream().filter((e) -> e.getSalary() >= 5000).skip(2).forEach(System.out::println);2.1.4 distinct:去重 必須重寫hashCode() 和 equals() (可以生成)才能去重
2.2 映射
2.2.1 map 接收lamda
接收一個函數作為參數,該函數會被應用到每個元素上,并將其映射成一個新的元素。
這里 toUpperCase這個函數應用到每個元素上,使每個元素都變為大寫,最后輸出結果
又比如 提取名字
2.2.2 flatMap 把多個流歸總成一個流
TestStreamAPI1.java中的一個方法
//將串變為流 public static Stream<Character> filterCharacter(String str){List<Character> list = new ArrayList<>();for (Character ch : str.toCharArray()) {list.add(ch);}return list.stream();} List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");Stream<Stream<Character>> stream2 = strList.stream().map(TestStreamAPI1::filterCharacter);stream2.forEach((sm) -> {sm.forEach(System.out::println);});
效果同下
2.2.3 reduce
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);//起始值 0 作為x ;y為list中1 累加結果為1 ;第二次x為1;y為2;依此累加Integer sum = list.stream().reduce(0, (x, y) -> x + y);System.out.println(sum);//55 List<Employee> emps = Arrays.asList(new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),new Employee(101, "張三", 18, 9999.99, Employee.Status.FREE),new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),new Employee(104, "趙六", 8, 7777.77, Employee.Status.BUSY),new Employee(104, "趙六", 8, 7777.77, Employee.Status.FREE),new Employee(104, "趙六", 8, 7777.77, Employee.Status.FREE),new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)); Optional<Double> op = emps.stream().map(Employee::getSalary).reduce(Double::sum);System.out.println(op.get());//48888.840000000012.2.4 collect
Employee.java以3.1中的為準
收集
聚合
// 集合數long count = emps.stream().collect(Collectors.counting());System.out.println(count);//7//求工資平均值Double avg = emps.stream().collect(Collectors.averagingDouble(Employee::getSalary));System.out.println(avg);//求工資總和Double sum = emps.stream() .collect(Collectors.summingDouble(Employee::getSalary));System.out.println(sum);//48888.84000000001Optional<Double> sum = emps.stream().map(Employee::getSalary).collect(Collectors.reducing(Double::sum));System.out.println(sum.get());//48888.84000000001//求工資最小的那個人信息Optional<Employee> op = emps.stream().collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));System.out.println(op.get());//Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]//求最大工資Optional<Double> max = emps.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));System.out.println(max.get());//9999.99DoubleSummaryStatistics dss = emps.stream().collect(Collectors.summarizingDouble(Employee::getSalary));System.out.println(dss.getMax());//9999.99分組
//根據狀態分組Map<Employee.Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));System.out.println(map);//{BUSY=[Employee [id=102, name=李四, age=59, salary=6666.66, status=BUSY], Employee [id=104, name=趙六, age=8, salary=7777.77, status=BUSY], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]], // FREE=[Employee [id=101, name=張三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=趙六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=趙六, age=8, salary=7777.77, status=FREE]], // VOCATION=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]]}//先按照狀態分再按照年齡分Map<Employee.Status, Map<String, List<Employee>>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {if(e.getAge() >= 60)return "老年";else if(e.getAge() >= 35)return "中年";elsereturn "成年";})));System.out.println(map);// {VOCATION={成年=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]]}, // BUSY={成年=[Employee [id=104, name=趙六, age=8, salary=7777.77, status=BUSY]], 中年=[Employee [id=102, name=李四, age=59, salary=6666.66, status=BUSY], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}, // FREE={成年=[Employee [id=101, name=張三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=趙六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=趙六, age=8, salary=7777.77, status=FREE]]}}//分區//按照工資分成兩區Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));System.out.println(map);//{false=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]], // true=[Employee [id=102, name=李四, age=59, salary=6666.66, status=BUSY], Employee [id=101, name=張三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=趙六, age=8, salary=7777.77, status=BUSY], Employee [id=104, name=趙六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=趙六, age=8, salary=7777.77, status=FREE], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}//連成字符串 String str = emps.stream().map(Employee::getName).collect(Collectors.joining("," , "----", "----"));System.out.println(str);//----李四,張三,王五,趙六,趙六,趙六,田七----3 終止操作
3.1 各種查找的方法
Employee.java(以這個實體類為準)
public class Employee {private int id;private String name;private int age;private double salary;private Status status;public Employee() {}public Employee(String name) {this.name = name;}public Employee(String name, int age) {this.name = name;this.age = age;}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, 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;}public String show() {return "測試方法引用!";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + id;result = prime * result + ((name == null) ? 0 : name.hashCode());long temp;temp = Double.doubleToLongBits(salary);result = prime * result + (int) (temp ^ (temp >>> 32));return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Employee other = (Employee) obj;if (age != other.age)return false;if (id != other.id)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))return false;return true;}@Overridepublic String toString() {return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + ", status=" + status+ "]";}public enum Status {FREE, BUSY, VOCATION;}}allMatch——檢查是否匹配所有元素
anyMatch——檢查是否至少匹配一個元素
noneMatch——檢查是否沒有匹配的元素
findFirst——返回第一個元素
Optional<Employee> op = emps.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();System.out.println(op.get());Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]
findAny——返回當前流中的任意元素
Optional<Employee> op2 = emps.parallelStream()//并行流,多線程同時找 誰找到算誰的 可能隨機出現.filter((e) -> e.getStatus().equals(Employee.Status.FREE)).findAny();System.out.println(op2.get());count——返回流中元素的總個數
long count = emps.stream().filter((e) -> e.getStatus().equals(Employee.Status.FREE)).count();System.out.println(count);//3max——返回流中最大值
Optional<Double> op = emps.stream().map(Employee::getSalary).max(Double::compare);System.out.println(op.get());//9999.99min——返回流中最小值
Optional<Employee> op2 = emps.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(op2.get());Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]
注意:流進行了終止操作后,不能再次使用
Stream<Employee> stream = emps.stream().filter((e) -> e.getStatus().equals(Employee.Status.FREE));long count = stream.count();stream.map(Employee::getSalary).max(Double::compare);4 并行流與串行流
繼承RecursiveTask 重寫compute()
總結
- 上一篇: Hystrix学习——(2)雪崩效应
- 下一篇: JavaScript — 浏览器事件、冒