二、StreamAPI
一、Stream是什么?
是數據通道,用于操作數據源(集合、數組等)所生成的元素序列。集合講的是數據,流講的是計算。
注意:
Stream不會存儲元素。
Stream不會改變源對象。相反,他們會返回一個持有結果的新Stream。
Stream操作是延遲執行的。這意味著他們會等到需要結果的時候才執行。
Stream操作的三個步驟:
創建Stream: ?一個數據源(如:集合、數組),獲取一個流
中間操作:一個中間操作鏈,對數據源的數據進行處理
終止操作(終端操作):一個終止操作,執行中間操作鏈,并產生結果。
二、創建Stream
1、Java8中的Collection接口被擴展,提供了兩個獲取流的方法。
default Stream<E> stream() : 返回一個順序流
default Stream<E> parallelStream() : 返回一個并行流
//1. Collection 提供了兩個方法 stream() 與 parallelStream()List<String> list = new ArrayList<>();Stream<String> stream = list.stream(); //獲取一個順序流Stream<String> parallelStream = list.parallelStream(); //獲取一個并行流2、由數組創建流
Java8中的Arrays的靜態方法stream()可以獲取數組流。
static <T> Stream<T> stream(T[] array): 返回一個流
重載形式,能夠處理基本類型的數組:
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)
//2. 通過 Arrays 中的 stream() 獲取一個數組流 Integer[] nums = new Integer[10]; Stream<Integer> stream1 = Arrays.stream(nums);3、由值創建流
可以使用靜態方法Stream.of(),通過顯示值創建一個流。它可以接收任意數量的參數。
public static<T> Stream<T> of(T... values) : 返回一個流
Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6);4、由函數創建無限流
可以使用靜態方法 Stream.iterate() 和Stream.generate(), 創建無限流。
迭代:public static<T> Stream<T> iterate(final T seed, final?UnaryOperator<T> f)
生成:public static<T> Stream<T> generate(Supplier<T> s)
//迭代 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);三、Stream的中間操作
多個中間操作可以連接起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何的處理!而在終止操作時一次性全部處理,稱為“”惰性求值“”。
1、篩選與切片
①filter
//內部迭代:迭代操作 Stream API 內部完成 @Testpublic void test2(){//所有的中間操作不會做任何的處理Stream<Employee> stream = emps.stream().filter((e) -> {System.out.println("測試中間操作");return e.getAge() <= 35;});//只有當做終止操作時,所有的中間操作會一次性的全部執行,稱為“惰性求值” stream.forEach(System.out::println);} //外部迭代 @Testpublic void test3(){Iterator<Employee> it = emps.iterator();while(it.hasNext()){System.out.println(it.next());}}②limit
@Testpublic void test4(){emps.stream().filter((e) -> {System.out.println("短路!"); // && ||return e.getSalary() >= 5000;}).limit(3).forEach(System.out::println);}③skip
@Testpublic void test5(){emps.parallelStream().filter((e) -> e.getSalary() >= 5000).skip(2).forEach(System.out::println);}④distinct
@Testpublic void test6(){emps.stream().distinct().forEach(System.out::println);}2、映射
①映射
@Testpublic void test1(){Stream<String> str = emps.stream().map((e) -> e.getName());System.out.println("-------------------------------------------");List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");Stream<String> stream = strList.stream().map(String::toUpperCase);stream.forEach(System.out::println);Stream<Stream<Character>> stream2 = strList.stream().map(TestStreamAPI1::filterCharacter);stream2.forEach((sm) -> {sm.forEach(System.out::println);});System.out.println("---------------------------------------------");Stream<Character> stream3 = strList.stream().flatMap(TestStreamAPI1::filterCharacter);stream3.forEach(System.out::println);} public static Stream<Character> filterCharacter(String str){List<Character> list = new ArrayList<>();for (Character ch : str.toCharArray()) {list.add(ch);}return list.stream();}
②排序
@Testpublic void test2(){emps.stream().map(Employee::getName).sorted().forEach(System.out::println);System.out.println("------------------------------------");emps.stream().sorted((x, y) -> {if(x.getAge() == y.getAge()){return x.getName().compareTo(y.getName());}else{return Integer.compare(x.getAge(), y.getAge());}}).forEach(System.out::println);}
③Stream終止操作
終止操作會從流的流水線生成結果。其結果可以是任何不是流的值,例如:List、Integer、甚至是void。
查找與匹配:
match
@Testpublic void test1(){boolean bl = emps.stream().allMatch((e) -> e.getStatus().equals(Status.BUSY));System.out.println(bl);boolean bl1 = emps.stream().anyMatch((e) -> e.getStatus().equals(Status.BUSY));System.out.println(bl1);boolean bl2 = emps.stream().noneMatch((e) -> e.getStatus().equals(Status.BUSY));System.out.println(bl2);}? find
@Testpublic void test2(){Optional<Employee> op = emps.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();System.out.println(op.get());System.out.println("--------------------------------");Optional<Employee> op2 = emps.parallelStream().filter((e) -> e.getStatus().equals(Status.FREE)).findAny();System.out.println(op2.get());}count、max、min
@Testpublic void test3(){long count = emps.stream().filter((e) -> e.getStatus().equals(Status.FREE)).count();System.out.println(count);Optional<Double> op = emps.stream().map(Employee::getSalary).max(Double::compare);System.out.println(op.get());Optional<Employee> op2 = emps.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(op2.get());}?進行了終止操作后不能再次使用
//注意:流進行了終止操作后,不能再次使用 @Testpublic void test4(){Stream<Employee> stream = emps.stream().filter((e) -> e.getStatus().equals(Status.FREE));long count = stream.count();stream.map(Employee::getSalary).max(Double::compare);}? 歸約
備注:map和reduce的連接通常稱為map-reduce模式,因Google 用它來進行網絡搜索而出名。
@Test public void test1(){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<Double> op = emps.stream().map(Employee::getSalary).reduce(Double::sum);System.out.println(op.get()); } //需求:搜索名字中 “六” 出現的次數 @Test public void test2(){Optional<Integer> sum = emps.stream().map(Employee::getName).flatMap(TestStreamAPI1::filterCharacter).map((ch) -> {if(ch.equals('六'))return 1;else return 0;}).reduce(Integer::sum);System.out.println(sum.get()); }?
? 收集
//collect——將流轉換為其他形式。接收一個 Collector接口的實現,用于給Stream中元素做匯總的方法 @Testpublic void test3(){List<String> list = emps.stream().map(Employee::getName).collect(Collectors.toList());list.forEach(System.out::println);System.out.println("----------------------------------");Set<String> set = emps.stream().map(Employee::getName).collect(Collectors.toSet());set.forEach(System.out::println);System.out.println("----------------------------------");HashSet<String> hs = emps.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));hs.forEach(System.out::println);} //分組 @Test public void test5(){Map<Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));System.out.println(map); } //多級分組 @Testpublic void test6(){Map<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);} //分區 @Testpublic void test7(){Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));System.out.println(map); }
Collector 接口中方法的實現決定了如何對流執行收集操作(如收集到 List、Set、Map)。但是 Collectors 實用類提供了很多靜態方法,可以方便地創建常見收集器實例,具體方法與實例如下表:
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/zhaobingqing/p/7196630.html
總結
以上是生活随笔為你收集整理的二、StreamAPI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CA搭建与证书申请
- 下一篇: wallfall瀑布流的jq实现