JDK8 Stream API
package com.hundsun.java.se.java8;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.junit.Test;
import java.sql.SQLOutput;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description: Stream API
* @author:zhangys
* @date:Created in 21:22 2018/12/30
* @Modified By:
*/
public class Demo3 {
/**
* stream 自己不會儲存元素
* stream不會改變原物件,相反,他們會返回一個持有結果的新stream
* stream操作是延遲的,這意味著他們會等到需要結果的時候才執行
*/
/**
* 一、stream的三個操作步驟
* 1、建立stream
* 2、中間操作
* 3、終止操作(終端操作)
*/
//建立stream
@Test
public void test1(){
//1 可以 通過collection 系列集合提供的stream()或者parallelstream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
//2 通過Arrays中的靜態方法stream()獲取陣列流
Employee[] emp = new Employee[10];
Stream<Employee> stream1 = Arrays.stream(emp);
//3 通過stream 類中的靜態方法of()
Stream<String> stream2 = Stream.of("aa","bbb","cc");
//4 建立無限流
//迭代
Stream<Integer> stream3 = Stream.iterate(0,(x) -> x + 2);
//只顯示10個
stream3.limit(10).forEach(System.out::println);
System.out.println("-------------------------------------------");
//生成
Stream.generate(() -> Math.random())
.limit(5)
.forEach(System.out::println);
}
/**
* 中間操作
* filter -- 接收lambda,從流中排除某些元素
* limit--截斷流,使其元素不超過給定元素
* skip(n) --跳過元素,返回一個扔掉了前n個元素的流。若流中元素不足n個,則返回一個空流,與limit(n)互補
* distinct--篩選,通過流所生產元素的hashcode()和equals()去除重複元素
*
*
* 對映
* map--接收lambda ,將引數轉換成其他形式或提取資訊。接收一個函式作為引數,該函式會被應用到每個元素上,並將其形成一個新的元素
*
* flatMap --接收一個函式作為引數,將流中的每一個值都轉換成另一個流,然後把所有流連線成一個流
*/
List<Employee> employees = Arrays.asList(
new Employee("zhangsan",19,9999.99,Employee.Status.BUSY),
new Employee("lisi",38,5555.55,Employee.Status.FREE),
new Employee("wangwu",50,6666.66, Employee.Status.VOCATION),
new Employee("zhaoliu",16,3333.33,Employee.Status.FREE),
new Employee("tianqi",18,7777.77,Employee.Status.VOCATION)
);
@Test
public void test2(){
Stream<Employee> s = employees.stream()
.filter((e) -> {
System.out.println("中間操作");
return e.getAge() > 35;
}
);
//終止操作
//多箇中間操作可以連線起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何的處理
//而在終止操作時一次性全部處理,稱為“惰性求值”
s.forEach(System.out::println);
}
/**
* limit
*/
@Test
public void test3(){
employees.stream().filter((e) -> e.getSalary() > 5000)
.limit(2)
.forEach(System.out::println);
}
/**
* skip
*/
@Test
public void test4(){
employees.stream().filter((e) -> e.getSalary() > 5000)
.skip(2)
.forEach(System.out::println);
}
/**
* distinct
*/
@Test
public void test5(){
employees.stream().filter((e) -> e.getSalary() > 5000)
.skip(2)
//去重必須重寫employmee的hashcode和equals方法 才能去重生效
.distinct()
.forEach(System.out::println);
}
/**
* 對映
*/
@Test
public void test6(){
List<String> list = Arrays.asList("aaa","bb","cc","sss");
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(Demo3::filterCharacter);
stream.forEach((s) ->{
s.forEach(System.out::println);
});
System.out.println("-------------------------");
Stream<Character> stream1 = list.stream().flatMap(Demo3::filterCharacter);
stream1.forEach(System.out::println);
}
public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (Character e : str.toCharArray()){
list.add(e);
}
return list.stream();
}
/**
* stream 排序
* sorted() --自然排序 (comparable)
* sorted(Comparator com) --定製排序(comparator)
*/
@Test
public void test7(){
List<String> list = Arrays.asList("aaaa","您好","sss","哈嘍","hello");
list.stream().sorted().forEach(System.out::println);
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);
}
/**
* 終止操作
* 1、stream 查詢和匹配
* allMatch--檢查是否匹配所有元素
* anyMatch--檢查是否至少匹配一個元素
* noneMatch--檢查是否沒有匹配的元素
* findFirst--返回第一個元素
* findAny--返回當前流中的任意元素
* count--返回流中元素的總個數
* max--返回流中的最大值
* min--返回流中最小值
*
* 2、歸約
* reduce(T identity,BinaryOperator) / reduce(BinaryOperator) --可以將流中元素反覆結合起來,得到一個值
*
*/
@Test
public void test8(){
boolean b1 = employees.stream()
.allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b1);
System.out.println("-------------------");
boolean b2 = employees.stream()
.anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b2);
System.out.println("---------------------");
boolean b3 = employees.stream()
.noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
Optional<Employee> emp1 = employees.stream()
.sorted((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary()))
.findFirst();
System.out.println("emp1:" + emp1.get());
System.out.println("--------------------");
Optional<Employee> emp2 = employees.stream()
.filter((e) -> e.getStatus().equals(Employee.Status.FREE))
.findAny();
System.out.println(emp2);
System.out.println("-----------------------");
Optional<Employee> emp3 = employees.parallelStream()
.filter((e) -> e.getStatus().equals(Employee.Status.FREE))
.findAny();
System.out.println(emp3);
System.out.println("---------------");
Long count = employees.stream().count();
System.out.println("-----------------" + count);
Optional<Employee> op = employees.stream().max((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary()));
System.out.println(op);
System.out.println("-------------------");
Optional<Double> op2 = employees.stream().map(Employee::getSalary).min(Double::compareTo);
System.out.println(op2.get());
}
/**
* 歸約
*/
/**
* 蒐集
*/
@Test
public void test9(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
Integer sum = list.stream().reduce(0,(x,y) -> x + y);
System.out.println(sum + "-------------------");
//OPtional 避免為null
Optional<Double> op = employees.stream().map(Employee::getSalary).reduce(Double::sum);
System.out.println(op.get() + " -----------------");
List<String> list1 = employees.stream().map(Employee::getName).collect(Collectors.toList());
list.forEach(System.out::println);
List<person> personList = Arrays.asList(new person(
"111","111","111"),
new person("111","222","222"),
new person("111","333","333"),
new person("111","444","444")
);
personList.forEach((e) -> e.setAge(e.getAge() + "age"));
System.out.println(personList);
HashSet<String> hs = employees.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
hs.forEach(System.out::println);
}
@Test
public void test10(){
//總數
Long count = employees.stream().collect(Collectors.counting());
System.out.println(count);
//平均數
System.out.println("----------------");
double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(avg);
//總和
Double sum = employees.stream().collect(Collectors.summingDouble(Employee::getSalary));
System.out.println(sum);
System.out.println("---------------------");
//最大值
Optional<Employee> max = employees.stream().collect(Collectors.maxBy((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary())));
System.out.println(max);
System.out.println("----------------");
//最小值
Optional<Double> min = employees.stream()
.map(Employee::getSalary)
.collect(Collectors.minBy((Double::compare)));
System.out.println(min);
//分組
Map<Employee.Status,List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
System.out.println(map);
//多級分組
Map<Employee.Status,Map<String,List<Employee>>> mapgroup = employees.stream().collect(Collectors.groupingBy(Employee::getStatus,Collectors.groupingBy((e) -> {
if (((Employee)e).getAge() <= 35){
return "青年";
} else if (((Employee)e).getAge() <=50){
return "中年";
} else {
return "老年";
}
})));
System.out.println(map);
//分割槽
Map<Boolean,List<Employee>> map2 = employees.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000));
System.out.println(map2);
//組函式
DoubleSummaryStatistics dss = employees.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(dss.getAverage());
System.out.println(dss.getCount());
System.out.println(dss.getMax());
String str = employees.stream()
.map(Employee::getName)
.collect(Collectors.joining(","));
}
class person{
private String name;
private String age;
private String status;
public person(String name, String age, String status) {
this.name = name;
this.age = age;
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public String toString() {
return "person{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
", status='" + status + '\'' +
'}';
}
}
}