Java 8 Stream

參考資料
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
https://www.cnblogs.com/aoeiuv/p/5911692.html
http://www.java2s.com/Tutorials/Java/Java_Stream/index.htm
https://blog.csdn.net/qq_28410283/article/details/80633292

流的操作類型

流的操作類型分為兩種:

Intermediate

一個(gè)流可以后面跟隨零個(gè)或多個(gè) intermediate 操作。其目的主要是打開流,做出某種程度的數(shù)據(jù)映射/過濾,然后返回一個(gè)新的流,交給下一個(gè)操作使用。

這類操作都是惰性化的(lazy),就是說,僅僅調(diào)用到這類方法,并沒有真正開始流的遍歷。

map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

Terminal

一個(gè)流只能有一個(gè) terminal 操作,當(dāng)這個(gè)操作執(zhí)行后,流就被使用“光”了,無法再被操作。所以這必定是流的最后一個(gè)操作。

Terminal 操作的執(zhí)行,才會(huì)真正開始流的遍歷,并且會(huì)生成一個(gè)結(jié)果,或者一個(gè) side effect。

forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
還有一種操作被稱為short-circuiting。用以指:

  • 對(duì)于一個(gè) intermediate 操作,如果它接受的是一個(gè)無限大(infinite/unbounded)的 Stream,但返回一個(gè)有限的新 Stream。
  • 對(duì)于一個(gè) terminal 操作,如果它接受的是一個(gè)無限大的 Stream,但能在有限的時(shí)間計(jì)算出結(jié)果。
    當(dāng)操作一個(gè)無限大的 Stream,而又希望在有限時(shí)間內(nèi)完成操作,則在管道內(nèi)擁有一個(gè) short-circuiting 操作是必要非充分條件。

anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

流只有在進(jìn)行Terminal或者個(gè)別Short-circuiting之后才會(huì)開始執(zhí)行

流無法復(fù)用,用完即銷毀

流的分類

特殊流

專門用于處理基本類型,int,double,long

IntStream,DoubleStream,LongStream

對(duì)象流

處理對(duì)象類型

流常用方法

import org.junit.Test;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import lombok.Data;
import lombok.experimental.Accessors;

public class StreamTest {
    /** 生成連續(xù)數(shù)字,含頭不含尾*/
    @Test
    public void testRange() {
        IntStream.range(0, 10).forEach(System.out::println);
    }
    
    /** 生成連續(xù)數(shù)字,含頭含尾*/
    @Test
    public void testRangeClosed() {
        IntStream.rangeClosed(0, 10).forEach(System.out::println);
    }
    
    /** 生成從0開始遞增3的前10位數(shù)字*/
    @Test
    public void testIterate() {
        IntStream.iterate(0, e -> e + 3).limit(10).forEach(System.out::println);
    }
    
    /** 生成從0開始遞增3,跳過前10位后的前5位數(shù)字*/
    @Test
    public void testSkip() {
        IntStream.iterate(0, e -> e + 3).skip(10).limit(5).forEach(System.out::println);
    }
    
    /** 生成當(dāng)前日期開始,遞增1天的前5位時(shí)間*/
    @Test
    public void testDateIterate() {
        Stream.iterate(LocalDate.now(), e -> e.plusDays(1)).limit(5).forEach(System.out::println);
    }

    /** 基本類型轉(zhuǎn)包裝類型*/
    @Test
    public void testBoxed() {
        List<Integer> collect = IntStream.range(10, 20).boxed().collect(Collectors.toList());
        System.out.println(collect);
    }

    /** 基本類型裝對(duì)象類型*/
    @Test
    public void testMapToObj() {
        List<TestPo> collect =
                IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e)).collect(Collectors.toList());
        System.out.println(collect);
    }

    /** 統(tǒng)計(jì)*/
    @Test
    public void testCount() {
        long count = IntStream.range(0, 10).count();
        System.out.println(count);
    }

    /** 去重*/
    @Test
    public void testDistinct() {
        IntStream.range(0, 10).map(e -> e % 2).forEach(System.out::println);
        IntStream.range(0, 10).map(e -> e % 2).mapToObj(e->new TestPo().setOrder(e)).distinct().forEach(System.out::println);
    }

    /** 求和*/
    @Test
    public void testSum() {
        int sum = IntStream.range(0, 10).sum();
        System.out.println(sum);
    }

    /** 過濾,保留filter中返回值為true的屬性*/
    @Test
    public void testFilter() {
        IntStream.range(0, 10).filter(e -> e >= 5).forEach(System.out::println);
    }

    /** 聚合操作*/
    @Test
    public void testReduce() {
        BigDecimal reduce =
                DoubleStream.iterate(1, e->e+1).limit(10).mapToObj(BigDecimal::valueOf).reduce(BigDecimal.ZERO,
                BigDecimal::add);
        System.out.println(reduce.toPlainString());
    }

    /** 把input Stream 中的層級(jí)結(jié)構(gòu)扁平化,就是將最底層元素抽出來放到一起,返回對(duì)象必須是Stream*/
    @Test
    public void testFlatMap() {
        List<Integer> collect = IntStream.rangeClosed(0, 10).boxed().collect(Collectors.toList());
        List<Integer> collect1 = IntStream.rangeClosed(5, 15).boxed().collect(Collectors.toList());
        List<Integer> collect2 = IntStream.rangeClosed(10, 20).boxed().collect(Collectors.toList());
        List<List<Integer>> list = new ArrayList<>();
        list.add(collect);
        list.add(collect1);
        list.add(collect2);
        System.out.println(list);
        List<Integer> collect3 = list.stream().flatMap(e -> e.stream()).collect(Collectors.toList());
        System.out.println(collect3);
    }

    /** 對(duì)每個(gè)元素執(zhí)行操作并返回一個(gè)新的 Stream*/
    @Test
    public void testPeek() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
                .collect(Collectors.toList());
        System.out.println(collect);
        List<TestPo> collect1 = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
                .peek(e -> e.setOrder(e.getOrder() + 10)).collect(Collectors.toList());
        System.err.println(collect1);
    }
    
    /** 聚合為map*/
    @Test
    public void testToMap() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
                .collect(Collectors.toList());
        Map<String, TestPo> collect1 = collect.stream().collect(Collectors.toMap(e -> e.getName(), e -> e));
        System.out.println(collect1);
    }

    /** 按指定屬性分組*/
    @Test
    public void testGroupingBy() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
                .collect(Collectors.toList());
        Map<Integer, List<TestPo>> collect1 = collect.stream().collect(Collectors.groupingBy(e -> e.getOrder()));
        System.out.println(collect1);
    }

    /** 按指定屬性分組后,對(duì)每組元素進(jìn)行操作*/
    @Test
    public void testGroupingByExpand() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
                .collect(Collectors.toList());

        Map<Integer, Set<String>> collect1 = collect.stream().collect(
                Collectors.groupingBy(e -> e.getOrder(), Collectors.mapping(e -> e.getName(), Collectors.toSet())));
        System.out.println(collect1);
    }

     /** 按指定屬性分組后,對(duì)每組元素進(jìn)行操作*/
    @Test
    public void testGroupingByExpand1() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
                .collect(Collectors.toList());
        Map<Integer, Long> collect1 =
                collect.stream().collect(Collectors.groupingBy(e -> e.getOrder(), Collectors.counting()));
        System.out.println(collect1);
    }

    /** 根據(jù)判斷條件對(duì)數(shù)據(jù)進(jìn)行分割,滿足條件的key為true*/
    @Test
    public void testPartitioningBy() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
                .collect(Collectors.toList());
        Map<Boolean, List<TestPo>> collect1 =
                collect.stream().collect(Collectors.partitioningBy(e -> e.getOrder() > 1));
        System.out.println(collect1);
    }

    /** 排序操作*/
    @Test
    public void testSort() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
                .collect(Collectors.toList());
        System.out.println(collect);
        collect.sort(Comparator.comparing(e -> e.getOrder()));
        System.out.println(collect);

    }

    /** 排序操作,可以多字段排序,可指定排序器,可控制null值處理及正序倒敘*/
    @Test
    public void testSorted() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e % 3).setName("test" + e))
                .sorted(Comparator.comparingInt(e -> e.getOrder())).collect(Collectors.toList());
        System.out.println(collect);
    }
    
    /** 并行流(fork join)*/
    @Test
    public void testParallel() {
        IntStream.range(0, 10).parallel().boxed().forEach(System.out::println);
    }

    /** 并行流(fork join)*/
    @Test
    public void testParallel1() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
                .collect(Collectors.toList());
        collect.parallelStream().map(e -> e.getOrder()).forEach(System.out::println);
        collect.parallelStream().map(e -> e.getOrder()).forEachOrdered(System.err::println);
    }
    
    /** 全部不匹配*/
    @Test
    public void testNoneMatch() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
                .collect(Collectors.toList());
        System.out.println(collect.stream().noneMatch(e -> e.getOrder() > 8));
    }

    /** 任意一個(gè)匹配*/
    @Test
    public void testAnyMatch() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
                .collect(Collectors.toList());
        System.out.println(collect.stream().anyMatch(e -> e.getOrder() > 8));
    }

    /** 全部匹配*/
    @Test
    public void testAllMatch() {
        List<TestPo> collect = IntStream.range(0, 10).mapToObj(e -> new TestPo().setOrder(e).setName("test" + e))
                .collect(Collectors.toList());
        System.out.println(collect.stream().allMatch(e -> e.getOrder() > 8));
    }


    @Data
    @Accessors(chain = true)
    public static class TestPo {
        private Integer order;
        private String name;
        private TestPo1 po1;
    
        @Data
        public static class TestPo1{
            private String age;
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容