Java8新特性之Stream的API常用函數(shù)使用及說明

因為學習了Lambda表達式,再學習Java8新特性之Stream的API常用函數(shù)使用及說明,兩者結(jié)合起來压彭,代碼就可以玩得更溜,下面做Stream的一些常用函數(shù)使用及說明渗常,方日后溫習壮不,如果發(fā)現(xiàn)有不足之處,請多多指教皱碘。

什么是Stream(流)询一?

Stream是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(如:集合癌椿,數(shù)組等)轉(zhuǎn)成的元素序列健蕊,對集合中的每個元素進行一系列并行或者串行的流水線操作。

Stream的作用是什么(為什么需要Stream)踢俄?

Stream是Java8的一大亮點缩功,它與java.io包中的InputStream、OutputStream是完全不同的概念都办;也不同于解析XML出來的Stream嫡锌。
Stream是java對集合對象功能的增強势木,對集合對象進行各種非常方便歌懒、高效的聚合操作,或者對大指數(shù)據(jù)操作及皂。Stream的API同樣借助于Lambda表達式(支持函數(shù)式編程,代碼非常簡潔)查剖,提高編程效率和程序的可讀性噪窘,同時它還提供了并行和串行這兩種模式進行匯聚操效扫。默認情況能充分利用cpu的資源(Stream操作是延遲執(zhí)行的直砂,需要結(jié)果的時候才執(zhí)行)。

Stream操作的三步曲

  1. 創(chuàng)建Stream:通過一個數(shù)據(jù)源(如:數(shù)組静暂,集合)济丘,獲到一個流。
  2. 中間操作:一個中間操作鏈(如:filter,map等)洽蛀,對數(shù)據(jù)源的數(shù)據(jù)進行處理摹迷。
  3. 終止操作:一個終止操作,執(zhí)行中間操作鏈郊供,并產(chǎn)生結(jié)果峡碉。
Stream的步驟.png

Stream創(chuàng)建的四種方式

  1. Collection提供了兩個方法,分別為stream()和parallelStream()驮审。

    //通過List集合創(chuàng)建Stream
    List<String> list = new ArrayList<>();
    Stream<String> stream1 = list.stream();//獲取一個順序流
    Stream<String> parallelStream = list.parallelStream(); //獲取一個并行流
    
  2. 通過Arrays中的靜態(tài)方法stream()獲取一個數(shù)組流鲫寄。

    //通過Arrays中的靜態(tài)方法stream()獲取一個數(shù)組流
    Student[] students = new Student[2];
    Stream<Student> stream = Arrays.stream(students);
    
  3. 通過Stream類中的靜態(tài)方法of()。注意:這里可以是字符串疯淫,數(shù)組地来,集合等其他數(shù)據(jù)類型。

    //通過Stream類中的靜態(tài)方法of()熙掺。注意:這里可以是字符串未斑,數(shù)組,集合等其他數(shù)據(jù)類型币绩。
    Stream<String> stream3 = Stream.of("java", "lambda", "stream", "6666");
    
  4. 創(chuàng)建無限流颂碧。

    //使用iterate()創(chuàng)建無限流,這個通常和limit()一起使用类浪,限制流中元素的個數(shù)。
    //iterate()接受一個種子值肌似,和一個UnaryOperator(例如 f)费就。然后種子值成為Stream的第一個元素,
    //f(seed) 為第二個川队,f(f(seed)) 第三個力细,以此類推.
    Stream<Integer> iterate = Stream.iterate(0, x -> x + 1);
    iterate.limit(5).forEach(System.out::println);
    
    //使用generate()創(chuàng)建無限流,通常跟limit()一起使用固额,限制流中元素的個數(shù)斗躏。
    //可以根據(jù)任何計算方式來生成,通過實現(xiàn)Supplier接口云稚,你可以自己來控制流的生成。
    Stream<Long> generate = Stream.generate(new Supplier<Long>() {
        long a = 1, b = 2;
        @Override
        public Long get() {
            long temp = a + b;
            a = b;
            b = temp;
            return a;
        }
    });
    generate.limit(10).forEach(System.out::println);
    

Stream的中間操作

中間操作符(如:filter,map等)鲸拥,多個中間操作可以連接起來形成一條流水線形式對數(shù)據(jù)源的數(shù)據(jù)進行處理刑赶。注意:如果未觸發(fā)終止操作(下面會進行介紹)角撞,中間操作是不會執(zhí)行任何處理,在觸發(fā)終止操作時會一次性全部執(zhí)行中間操作鏈并產(chǎn)生結(jié)果劣领。

中間操作有狀態(tài)之分:無狀態(tài)——指元素的處理不受之前元素的影響尖淘;有狀態(tài)——指該操作只有拿到所有元素之后才能繼續(xù)下去村生。

中間操作

Stream的終止操作(結(jié)束操作)

一個終止操作,執(zhí)行中間操作鏈卫病,并產(chǎn)生結(jié)果蟀苛。終止操作有狀態(tài)之分:非短路——指必須處理所有元素才能得到最終結(jié)果帜平;短路——指遇到某些符合條件的元素就可以得到最終結(jié)果评腺,如 A || B蒿讥,只要A為true芋绸,則無需判斷B的結(jié)果。

終止操作

Stream的實際操作

我們了解了Java8新特性Stream的API后马昙,開始以代碼實踐操作一遍行楞。

一子房、中間操作就是對容器(集合)的處理過程证杭,包括:篩選(filter、limit乎莉、distinct梦鉴、skip...)肥橙,映射(map存筏、flatMap...)予跌,排序(sorted...)券册,消費(peek..)等 烁焙。先寫一個學生科目分數(shù)對象骄蝇,以便操作九火。

public class StudentSubject {
    private String studentName;
    private String subject;
    private Integer score;

    public StudentSubject(String studentName, String subject, Integer score) {
        this.studentName = studentName;
        this.subject = subject;
        this.score = score;
    }
    public String getStudentName() {
        return studentName;
    }
    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public Integer getScore() {
        return score;
    }
    public void setScore(Integer score) {
        this.score = score;
    }
    @Override
    public String toString() {
        return "StudentSubject{" +
                "studentName='" + studentName + '\'' +
                ", subject='" + subject + '\'' +
                ", score=" + score +
                '}';
    }
     @Override
    public boolean equals(final Object obj) {
        if (obj == null) {
            return false;
        }
        final StudentSubject ss = (StudentSubject) obj;
        if (this == ss) {
            return true;
        } else {
            return (this.studentName.equals(ss.studentName));
        }
    }
    @Override
    public int hashCode() {
        int hash_code = 7;
        hash_code = 13 * hash_code+ (studentName == null ? 0 : studentName.hashCode());
        return hash_code;
    }
}

注意:因為中間操作鏈在沒有執(zhí)行終止操作前是不會執(zhí)行的跨细,所有下面都是以執(zhí)行forEach終止操作來驗證中間操作鏈的使用冀惭。

篩選(filter散休、limit戚丸、distinct夺颤、skip...)

  • filter()世澜,過濾掉某些元素寥裂。如:獲取大90的科目信息

    StudentSubject s1 = new StudentSubject("張三", "語文", 85);
    StudentSubject s2 = new StudentSubject("小李", "語文", 91);
    StudentSubject s3 = new StudentSubject("張三", "數(shù)學", 95);
    StudentSubject s4 = new StudentSubject("小李", "數(shù)學", 95);
    StudentSubject s5 = new StudentSubject("張三", "英語", 92);
    
    List<StudentSubject> list = new ArrayList<>();
    list.add(s1);
    list.add(s2);
    list.add(s3);
    list.add(s4);
    list.add(s5);
    
    //獲取大90的科目信息
    list.stream().filter(item->item.getScore()>90).forEach(System.out::println);
    
    //輸出的結(jié)果為
    StudentSubject{studentName='小李', subject='語文', score=91}
    StudentSubject{studentName='張三', subject='數(shù)學', score=95}
    StudentSubject{studentName='小李', subject='數(shù)學', score=95}
    StudentSubject{studentName='張三', subject='英語', score=92}
    
  • limit()麻养,截斷流鳖昌,使其元素不超過給定的數(shù)量遗遵。

    //截流车要,取前面三個元素信息
    list.stream().limit(3).forEach(System.out::println);
    
    //打印結(jié)果
    StudentSubject{studentName='張三', subject='語文', score=85}
    StudentSubject{studentName='小李', subject='語文', score=91}
    StudentSubject{studentName='張三', subject='數(shù)學', score=95}
    
  • distinct()翼岁,通過流所生成的元素的hashCode()和equals()去除重復元素琅坡。

    注意:這里有坑,要讓distinct起作用坞淮,就必須在對應實體類中重寫HashCode和equals方法诺擅。

    //通過流所生成的元素的hashCode()和equals()去除重復元素烁涌。
    list.stream().distinct().forEach(System.out::println);
    //打印結(jié)果
    StudentSubject{studentName='張三', subject='語文', score=85}
    StudentSubject{studentName='小李', subject='語文', score=91}
    
    List<String> stringList = Arrays.asList("aa","bb","cc","aa","bb","cc");
    stringList.stream().distinct().forEach(System.out::println);
    //打印結(jié)果
    aa
    bb
    cc
    
  • skip(), 跳過元素抒钱,返回一個扔掉了前N個元素的流。 如果流中元素N個瑞信,則是返回一個空流凡简。與limit(n)互補秤涩。

    //扔掉前面三個元素
    list.stream().skip(3).forEach(System.out::println);
    //打印結(jié)果
    StudentSubject{studentName='小李', subject='數(shù)學', score=95}
    StudentSubject{studentName='張三', subject='英語', score=92}
    

映射(map、flatMap...)

  • map()匀谣,接收一個函數(shù)作為參數(shù),該函數(shù)會被應用到每一個元素上溶锭,并將其他映射成一個新的元素。

    //>=95分的就輸入科目信息,否則就為null
    list.stream().map(item->{
        if(item.getScore()>=95){
            return item;
        }
        return null;
    }).forEach(System.out::println);
    //打印結(jié)果
    null
    null
    StudentSubject{studentName='張三', subject='數(shù)學', score=95}
    StudentSubject{studentName='小李', subject='數(shù)學', score=95}
    null
    
    //>=95分的就輸入true露久,否則就為false
    list.stream().map(item->item.getScore()>=95).forEach(System.out::println);
    //打印結(jié)果
    false
    false
    true
    true
    false
        
    //寫法2 涉及到collect終止操作毫痕,下面會詳細說。
    //>=95分的就輸入科目信息臊泰,否則就為null
    List<StudentSubject> studentSubjectStream = list.stream().map(item -> {
        if (item.getScore() >= 95) {
            return item;
        }
        return null;
    }).collect(Collectors.toList());
    studentSubjectStream.forEach(System.out::println);
    //>=95分的就輸入true,否則就為false
    List<Boolean> booleanStream = list.stream().map(item -> item.getScore() >= 95)
        .collect(Collectors.toList());
    booleanStream.forEach(System.out::println);
    
  • mapToInt

    //mapToInt 跟map都類似的蚜枢,只是類型被限定為IntStream缸逃。
    IntSummaryStatistics intSummaryStatistics = list.stream().mapToInt(person-> person.getScore()).summaryStatistics();
    System.out.println("最大分數(shù):"+intSummaryStatistics.getMax()); //最大值
    System.out.println("最小分數(shù):"+intSummaryStatistics.getMin()); //最小值
    System.out.println("分數(shù)總和:"+intSummaryStatistics.getSum()); //總計
    System.out.println("信息條數(shù):"+intSummaryStatistics.getCount());//個數(shù)
    System.out.println("平均分數(shù):"+intSummaryStatistics.getAverage());//平均數(shù)返回的是double類型
    
  • mapToLong针饥、mapToDouble 跟map都類似的,只是類型被限定為不同類型而已需频。這里就不舉例了丁眼。注意:沒有float類型。

  • flatMap(..) 接收一個函數(shù)作為參數(shù)昭殉,將流中的每個值都換成另一個流苞七,然后把所有流連接成一個流惠啄。這個過程也稱為元素拍平拍扁族奢。

    //把每學生科目分數(shù)信息轉(zhuǎn)成一個新有流
    list.stream().flatMap(item->{
        //將每個元素轉(zhuǎn)換成一個stream
        String[] info = {item.getStudentName()+"_"+item.getSubject()+"_"+item.getScore()};
        Stream<String> newStream = Arrays.stream(info);
        return newStream;
    }).forEach(System.out::println);
    //打印結(jié)果
    張三_語文_85
    小李_語文_91
    張三_數(shù)學_95
    小李_數(shù)學_95
    張三_英語_92
    
  • flatMapToInt() 跟flatMap的作用一樣 只是類型被限定為IntStream。

    //flatMapToInt(..) 和 flatMap的作用一樣 只是類型被限定為IntStream
    IntStream intStream =list.stream()
        .flatMapToInt(item ->IntStream.of(item.getScore()));
    intStream.forEach(System.out::println);
    //打印結(jié)果
    85
    91
    95
    95
    92
    
  • faltMapToLong囤锉、faltMapToDouble 跟faltMap都類似的驱入,只是類型被限定為不同類型而已癣朗。這里就不舉例了蠢熄。注意:沒有float類型饥追。

排序(sorted...)

  • sorted()捏顺, 排序 底層依賴Comparable 實現(xiàn)主巍,也可以提供自定義比較器。

    //sorted(), 排序,底層依賴Comparable實現(xiàn)翁垂,也可以提供自定義比較器。
    //底層依賴Comparable
    Stream.of(1,1,0,8,2,4,6).sorted().forEach(System.out::println);
    list.stream()
        //自定義比較器  按分數(shù)由高到低
        .sorted((ss1,ss2)->ss1.getScore()<ss2.getScore()?1:ss1.getScore()==ss2.getScore()?0:-1)
        .forEach(System.out::println);
    //打印結(jié)果
    0
    1
    1
    2
    4
    6
    8
    StudentSubject{studentName='張三', subject='數(shù)學', score=95}
    StudentSubject{studentName='小李', subject='數(shù)學', score=95}
    StudentSubject{studentName='張三', subject='英語', score=92}
    StudentSubject{studentName='小李', subject='語文', score=91}
    StudentSubject{studentName='張三', subject='語文', score=85}
    
    

消費(peek...)

  • peek() 挑選,如同于map,能得到流中的每一個元素车海。但map接收的是一個Function表達式,有返回值致板;而peek接收的是Consumer表達式亚享,沒有返回值情组〉树蓿可以理解為提前消費。

    //所有同學所有科目都是100分,哈哈
    list.stream().peek(item->item.setScore(100)).forEach(System.out::println);
    //打印結(jié)果
    StudentSubject{studentName='張三', subject='語文', score=100}
    StudentSubject{studentName='小李', subject='語文', score=100}
    StudentSubject{studentName='張三', subject='數(shù)學', score=100}
    StudentSubject{studentName='小李', subject='數(shù)學', score=100}
    StudentSubject{studentName='張三', subject='英語', score=100}
    

二、終止操作人灼,執(zhí)行中間操作鏈投放,并產(chǎn)生結(jié)果蕊肥。當這個操作執(zhí)行后琅锻,流就被使用“光”了茧彤,無法再被操作。所以這必定是流的最后一個操作疆栏。之后如果想要操作就必須新打開流曾掂。終止操作包括:循環(huán)遍歷操作(forEach、forEachOrdered)壁顶、收集操作(collect..)珠洗、 匹配與聚合操作(allMatch、max博助、min...)

循環(huán)遍歷操作

  • forEach()、forEachOrdered()痹愚,遍歷操作 富岳,對每個數(shù)據(jù)遍歷迭代。

    forEach()在上面的例子已使用過拯腮,就不舉例了窖式。注意:forEach是一個終端操作,參數(shù)也是一個函數(shù)动壤,它會迭代中間操作完成后的每一個數(shù)據(jù)萝喘。

    forEachOrdered適用于并行流的情況下進行迭代,能確保迭代的有序性琼懊。如下面例子:

    Stream.of(1,3,7,5,4,9,8,-1)
        .parallel()
        .forEachOrdered(item->
                        System.out.println(Thread.currentThread().getName()+": "+item));
    //打印的結(jié)果
    ForkJoinPool.commonPool-worker-4: 1
    ForkJoinPool.commonPool-worker-2: 3
    ForkJoinPool.commonPool-worker-2: 7
    ForkJoinPool.commonPool-worker-2: 5
    ForkJoinPool.commonPool-worker-2: 4
    ForkJoinPool.commonPool-worker-2: 9
    ForkJoinPool.commonPool-worker-2: 8
    ForkJoinPool.commonPool-worker-2: -1
    

    parallel()提供并行操作的支持阁簸。并行這一塊知識,先不在這里深入哼丈。

收集操作

  • collect()启妹,收集操作,接收一個Collector接口的實現(xiàn)醉旦,將流轉(zhuǎn)換為其他形式(收集到List饶米,Set桨啃,Map等容器中)。

    //collect:接收一個Collector實例檬输,將流中元素收集成另外一個數(shù)據(jù)結(jié)構(gòu)照瘾。
    System.out.println("==========將分數(shù) 裝成list=========");
    //將分數(shù) 裝成list
    List<Integer> scoreList = list.stream().map(StudentSubject::getScore)
        .collect(Collectors.toList());
    scoreList.forEach(System.out::println);
    
    System.out.println("=========轉(zhuǎn)成set==========");
    //轉(zhuǎn)成set
    Set<Integer> scoreSet = list.stream().map(StudentSubject::getScore)
        .collect(Collectors.toSet());
    scoreSet.forEach(System.out::println);
    
    System.out.println("=========轉(zhuǎn)成map==========");
    //轉(zhuǎn)成map,注:key不能相同,否則報錯
    Map<String,Integer> map = list.stream()
        .collect(Collectors.toMap(StudentSubject::getSubject, StudentSubject::getScore));
    map.forEach((k,v)->System.out.println(k+":"+v));
    
    System.out.println("=========字符串分隔符連接==========");
    //字符串分隔符連接
    String subjectName = list.stream().map(StudentSubject::getSubject)
        .collect(Collectors.joining(",", "(", ")"));
    System.out.println(subjectName);
    
    //打印結(jié)果
    ==========將分數(shù) 裝成list=========
    85
    95
    92
    =========轉(zhuǎn)成set==========
    85
    92
    95
    =========轉(zhuǎn)成map==========
    數(shù)學:95
    語文:85
    英語:92
    =========字符串分隔符連接==========
    (語文,數(shù)學,英語)
    

    注意下面的兩種寫法的不同之處丧慈。

    //寫法一
    Stream.of("java", "ios", "android", "h5", "rn")
                    .collect(Collectors.toSet()) //set 容器
                    .forEach(e -> System.out.println(e));
    //寫法二
    Set<String> setList = Stream.of("java", "ios", "android", "h5", "rn")
                    .collect(Collectors.toSet()) ;
    setList.forEach(e -> System.out.println(e));
    

    寫法一中collect和forEach同時使用了終止操作符析命,大家都會想到終止操作不是只能用一次就終止了么?其實forEach不僅僅是Stream中得操作符還是各種集合中得一個語法糖伊滋。

匹配碳却、聚合操作

  • allMatch:匹配操作,接收一個 Predicate 函數(shù)笑旺,當流中每個元素都符合該斷言時才返回true昼浦,否則返回false
    noneMatch:匹配操作,接收一個 Predicate 函數(shù)筒主,當流中每個元素都不符合該斷言時才返回true关噪,否則返回false
    anyMatch:匹配操作,接收一個 Predicate 函數(shù)乌妙,只要流中有一個元素滿足該斷言則返回true使兔,否則返回false
    findFirst:查找操作,返回流中第一個元素
    findAny:查找操作藤韵,返回流中的任意元素
    count:聚合操作虐沥,返回流中元素的總個數(shù)
    max:匹配操作,返回流中元素最大值
    min:匹配操作泽艘,返回流中元素最小值

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    boolean allMatch = list.stream().allMatch(e -> e > 10);
    System.out.println("allMatch: "+allMatch);
    boolean noneMatch = list.stream().noneMatch(e -> e > 10);
    System.out.println("noneMatch: "+noneMatch);
    boolean anyMatch = list.stream().anyMatch(e -> e > 5);
    System.out.println("anyMatch: "+anyMatch);
    Integer findFirst = list.stream().findFirst().get();
    System.out.println("findFirst: "+findFirst);
    Integer findAny = list.stream().findAny().get();
    System.out.println("findAny: "+findAny);
    long count = list.stream().count();
    System.out.println("count: "+count);
    Integer max = list.stream().max(Integer::compareTo).get();
    System.out.println("max: "+max);
    Integer min = list.stream().min(Integer::compareTo).get();
    System.out.println("min: "+min);
    
    //打印結(jié)果
    allMatch: false
    noneMatch: true
    anyMatch: true
    findFirst: 1
    findAny: 1
    count: 9
    max: 9
    min: 1
    

歸約操作

  • reduce()欲险,歸約操作,把整個數(shù)據(jù)流的值歸約為一個值(比如對所有元素求和匹涮,乘啊等)天试。(如:count、max然低、min操作的底層就是運用了歸約操作)

    Optional reduce(BinaryOperator accumulator):

    第一次執(zhí)行時喜每,accumulator函數(shù)的第一個參數(shù)為流中的第一個元素,第二個參數(shù)為流中元素的第二個元素雳攘;第二次執(zhí)行時带兜,第一個參數(shù)為第一次函數(shù)執(zhí)行的結(jié)果,第二個參數(shù)為流中的第三個元素吨灭;依次類推鞋真。

    T reduce(T identity, BinaryOperator accumulator):

    流程跟上面一樣,只是第一次執(zhí)行時沃于,accumulator函數(shù)的第一個參數(shù)為identity涩咖,而第二個參數(shù)為流中的第一個元素海诲。

    U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator combiner):

    在串行流(stream)中,該方法跟第二個方法一樣檩互,即第三個參數(shù)combiner不會起作用特幔。在并行流(parallelStream)中,我們知道流被fork join出多個線程進行執(zhí)行,此時每個線程的執(zhí)行流程就跟第二個方法reduce(identity,accumulator)一樣闸昨,而第三個參數(shù)combiner函數(shù)蚯斯,則是將每個線程的執(zhí)行結(jié)果當成一個新的流,然后使用第一個方法reduce(accumulator)流程進行歸約饵较。

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    
    Integer v = list.stream().reduce((x1, x2) -> x1 + x2).get();
    System.out.println("v:"+v);
    Integer v1 = list.stream().reduce(10, (x1, x2) -> x1 + x2);
    System.out.println("v1:"+v1);
    
    Integer v2 = list.stream().reduce(0,
                                      (x1, x2) -> {
                                          System.out.println("stream accumulator: x1:" + x1 + " x2:" + x2);
                                          return x1 - x2;
                                      },
                                      (x1, x2) -> {
                                          System.out.println("stream combiner: x1:" + x1 + " x2:" + x2);
                                          return x1 * x2;
                                      });
    System.out.println("v2:"+v2);
    //并行流
    Integer v3 = list.parallelStream().reduce(0,
                                              (x1, x2) -> {
                                                  System.out.println("parallelStream accumulator: x1:" + x1 + " x2:" + x2);
                                                  return x1 - x2;
                                              },
                                              (x1, x2) -> {
                                                  System.out.println("parallelStream combiner: x1:" + x1 + " x2:" + x2);
                                                  return x1 * x2;
                                              });
    System.out.println("v3:"+v3);
    
    //打印的結(jié)果
    v:120
    v1:130
    v2:-120
    v3:-2004310016
    

轉(zhuǎn)換操作

  • toArray()拍嵌,轉(zhuǎn)成數(shù)組,可以提供自定義數(shù)組生成器循诉。

    Object aa[] = Stream.of("android","java","IOS").toArray();
            
    StudentSubject s1 = new StudentSubject("張三", "語文", 85);
    StudentSubject s2 = new StudentSubject("張三", "數(shù)學", 95);
    StudentSubject s3 = new StudentSubject("張三", "英語", 92);
    StudentSubject s4 = new StudentSubject("張三", "物理", 92);
    List<StudentSubject> list = Arrays.asList(s1,s2,s3,s4);
    //調(diào)用的stream的toArray的函數(shù)
    String[] ss = list.stream().toArray(str -> new String[list.size()]);
    String[] ss1 = list.stream().toArray(String[]::new);
    Object[] obj1 = list.stream().toArray();
    //直接調(diào)用的List接口的toArray函數(shù)
    String[] ss2 = list.toArray(new String[list.size()]);
    Object[] obj2 = list.toArray();
    

    前三個横辆,是調(diào)用的stream的toArray的函數(shù),后面的兩個茄猫,是直接調(diào)用的List接口的toArray函數(shù)狈蚤。

總結(jié)

  • 了解Stream含義
  • 了解Stream的作用
  • 了解Stream的操作步驟
  • 對Stream的Api的常用函數(shù)進行操作及匯總

注意

  • 集合講的是數(shù)據(jù),流講的計算划纽。
  • Stream本身不會存儲元素脆侮。
  • Stream不會改變源對象,但它會返回一個持有結(jié)果的新Stream勇劣。
  • Stream操作是延遲執(zhí)行的靖避。這就意味著他們會等到需要結(jié)果的時候才執(zhí)行。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末比默,一起剝皮案震驚了整個濱河市幻捏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌退敦,老刑警劉巖粘咖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚣抗,死亡現(xiàn)場離奇詭異侈百,居然都是意外死亡,警方通過查閱死者的電腦和手機翰铡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門钝域,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锭魔,你說我怎么就攤上這事例证。” “怎么了迷捧?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵织咧,是天一觀的道長胀葱。 經(jīng)常有香客問我,道長笙蒙,這世上最難降的妖魔是什么抵屿? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮捅位,結(jié)果婚禮上轧葛,老公的妹妹穿的比我還像新娘。我一直安慰自己艇搀,他們只是感情好尿扯,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著焰雕,像睡著了一般衷笋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上淀散,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天右莱,我揣著相機與錄音,去河邊找鬼档插。 笑死慢蜓,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的郭膛。 我是一名探鬼主播晨抡,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼则剃!你這毒婦竟也來了耘柱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤棍现,失蹤者是張志新(化名)和其女友劉穎调煎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體己肮,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡士袄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谎僻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娄柳。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖艘绍,靈堂內(nèi)的尸體忽然破棺而出赤拒,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布挎挖,位于F島的核電站这敬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蕉朵。R本人自食惡果不足惜鹅颊,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望墓造。 院中可真熱鬧堪伍,春花似錦、人聲如沸觅闽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛉拙。三九已至尸闸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孕锄,已是汗流浹背吮廉。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畸肆,地道東北人宦芦。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像轴脐,于是被迫代替她去往敵國和親调卑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自: Java 8 中的 Streams API 詳解 為什么需要 Stream Stream 作為 Java ...
    普度眾生的面癱青年閱讀 2,921評論 0 11
  • 了解Stream ? Java8中有兩個最為重要的改變大咱,一個是Lambda表達式恬涧,另一個就是Stream AP...
    龍歷旗閱讀 3,328評論 3 4
  • Java 8自Java 5(發(fā)行于2004)以來最具革命性的版本。Java 8 為Java語言碴巾、編譯器溯捆、類庫、開發(fā)...
    誰在烽煙彼岸閱讀 891評論 0 4
  • Java 8自Java 5(發(fā)行于2004)以來最具革命性的版本厦瓢。Java 8 為Java語言提揍、編譯器、類庫旷痕、開發(fā)...
    huoyl0410閱讀 637評論 1 2
  • 1. 什么是λ表達式 λ表達式本質(zhì)上是一個匿名方法碳锈。讓我們來看下面這個例子: public int add(int...
    黎景陽閱讀 2,160評論 1 3