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

因?yàn)閷W(xué)習(xí)了Lambda表達(dá)式,再學(xué)習(xí)Java8新特性之Stream的API常用函數(shù)使用及說明,兩者結(jié)合起來,代碼就可以玩得更溜,下面做Stream的一些常用函數(shù)使用及說明,方日后溫習(xí),如果發(fā)現(xiàn)有不足之處,請(qǐng)多多指教。

什么是Stream(流)?

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

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

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

Stream操作的三步曲

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

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

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

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

    //通過Arrays中的靜態(tài)方法stream()獲取一個(gè)數(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)建無限流,這個(gè)通常和limit()一起使用,限制流中元素的個(gè)數(shù)。
    //iterate()接受一個(gè)種子值,和一個(gè)UnaryOperator(例如 f)。然后種子值成為Stream的第一個(gè)元素,
    //f(seed) 為第二個(gè),f(f(seed)) 第三個(gè),以此類推.
    Stream<Integer> iterate = Stream.iterate(0, x -> x + 1);
    iterate.limit(5).forEach(System.out::println);
    
    //使用generate()創(chuàng)建無限流,通常跟limit()一起使用,限制流中元素的個(gè)數(shù)。
    //可以根據(jù)任何計(jì)算方式來生成,通過實(shí)現(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等),多個(gè)中間操作可以連接起來形成一條流水線形式對(duì)數(shù)據(jù)源的數(shù)據(jù)進(jìn)行處理。注意:如果未觸發(fā)終止操作(下面會(huì)進(jìn)行介紹),中間操作是不會(huì)執(zhí)行任何處理,在觸發(fā)終止操作時(shí)會(huì)一次性全部執(zhí)行中間操作鏈并產(chǎn)生結(jié)果。

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

中間操作

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

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

終止操作

Stream的實(shí)際操作

我們了解了Java8新特性Stream的API后,開始以代碼實(shí)踐操作一遍。

一、中間操作就是對(duì)容器(集合)的處理過程,包括:篩選(filter、limit、distinct、skip...),映射(map、flatMap...),排序(sorted...),消費(fèi)(peek..)等 。先寫一個(gè)學(xué)生科目分?jǐn)?shù)對(duì)象,以便操作。

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;
    }
}

注意:因?yàn)橹虚g操作鏈在沒有執(zhí)行終止操作前是不會(huì)執(zhí)行的,所有下面都是以執(zhí)行forEach終止操作來驗(yàn)證中間操作鏈的使用。

篩選(filter、limit、distinct、skip...)

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

    StudentSubject s1 = new StudentSubject("張三", "語文", 85);
    StudentSubject s2 = new StudentSubject("小李", "語文", 91);
    StudentSubject s3 = new StudentSubject("張三", "數(shù)學(xué)", 95);
    StudentSubject s4 = new StudentSubject("小李", "數(shù)學(xué)", 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ù)學(xué)', score=95}
    StudentSubject{studentName='小李', subject='數(shù)學(xué)', score=95}
    StudentSubject{studentName='張三', subject='英語', score=92}
    
  • limit(),截?cái)嗔鳎蛊湓夭怀^給定的數(shù)量。

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

    注意:這里有坑,要讓distinct起作用,就必須在對(duì)應(yīng)實(shí)體類中重寫HashCode和equals方法。

    //通過流所生成的元素的hashCode()和equals()去除重復(fù)元素。
    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(), 跳過元素,返回一個(gè)扔掉了前N個(gè)元素的流。 如果流中元素N個(gè),則是返回一個(gè)空流。與limit(n)互補(bǔ)。

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

映射(map、flatMap...)

  • map(),接收一個(gè)函數(shù)作為參數(shù),該函數(shù)會(huì)被應(yīng)用到每一個(gè)元素上,并將其他映射成一個(gè)新的元素。

    //>=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ù)學(xué)', score=95}
    StudentSubject{studentName='小李', subject='數(shù)學(xué)', 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終止操作,下面會(huì)詳細(xì)說。
    //>=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("最大分?jǐn)?shù):"+intSummaryStatistics.getMax()); //最大值
    System.out.println("最小分?jǐn)?shù):"+intSummaryStatistics.getMin()); //最小值
    System.out.println("分?jǐn)?shù)總和:"+intSummaryStatistics.getSum()); //總計(jì)
    System.out.println("信息條數(shù):"+intSummaryStatistics.getCount());//個(gè)數(shù)
    System.out.println("平均分?jǐn)?shù):"+intSummaryStatistics.getAverage());//平均數(shù)返回的是double類型
    
  • mapToLong、mapToDouble 跟map都類似的,只是類型被限定為不同類型而已。這里就不舉例了。注意:沒有float類型。

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

    //把每學(xué)生科目分?jǐn)?shù)信息轉(zhuǎn)成一個(gè)新有流
    list.stream().flatMap(item->{
        //將每個(gè)元素轉(zhuǎn)換成一個(gè)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ù)學(xué)_95
    小李_數(shù)學(xué)_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 實(shí)現(xiàn),也可以提供自定義比較器。

    //sorted(), 排序,底層依賴Comparable實(shí)現(xiàn),也可以提供自定義比較器。
    //底層依賴Comparable
    Stream.of(1,1,0,8,2,4,6).sorted().forEach(System.out::println);
    list.stream()
        //自定義比較器  按分?jǐn)?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ù)學(xué)', score=95}
    StudentSubject{studentName='小李', subject='數(shù)學(xué)', score=95}
    StudentSubject{studentName='張三', subject='英語', score=92}
    StudentSubject{studentName='小李', subject='語文', score=91}
    StudentSubject{studentName='張三', subject='語文', score=85}
    
    

消費(fèi)(peek...)

  • peek() 挑選,如同于map,能得到流中的每一個(gè)元素。但map接收的是一個(gè)Function表達(dá)式,有返回值;而peek接收的是Consumer表達(dá)式,沒有返回值??梢岳斫鉃樘崆跋M(fèi)。

    //所有同學(xué)所有科目都是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ù)學(xué)', score=100}
    StudentSubject{studentName='小李', subject='數(shù)學(xué)', score=100}
    StudentSubject{studentName='張三', subject='英語', score=100}
    

二、終止操作,執(zhí)行中間操作鏈,并產(chǎn)生結(jié)果。當(dāng)這個(gè)操作執(zhí)行后,流就被使用“光”了,無法再被操作。所以這必定是流的最后一個(gè)操作。之后如果想要操作就必須新打開流。終止操作包括:循環(huán)遍歷操作(forEach、forEachOrdered)、收集操作(collect..)、 匹配與聚合操作(allMatch、max、min...)

循環(huán)遍歷操作

  • forEach()、forEachOrdered(),遍歷操作 ,對(duì)每個(gè)數(shù)據(jù)遍歷迭代。

    forEach()在上面的例子已使用過,就不舉例了。注意:forEach是一個(gè)終端操作,參數(shù)也是一個(gè)函數(shù),它會(huì)迭代中間操作完成后的每一個(gè)數(shù)據(jù)。

    forEachOrdered適用于并行流的情況下進(jìn)行迭代,能確保迭代的有序性。如下面例子:

    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()提供并行操作的支持。并行這一塊知識(shí),先不在這里深入。

收集操作

  • collect(),收集操作,接收一個(gè)Collector接口的實(shí)現(xiàn),將流轉(zhuǎn)換為其他形式(收集到List,Set,Map等容器中)。

    //collect:接收一個(gè)Collector實(shí)例,將流中元素收集成另外一個(gè)數(shù)據(jù)結(jié)構(gòu)。
    System.out.println("==========將分?jǐn)?shù) 裝成list=========");
    //將分?jǐn)?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不能相同,否則報(bào)錯(cuò)
    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é)果
    ==========將分?jǐn)?shù) 裝成list=========
    85
    95
    92
    =========轉(zhuǎn)成set==========
    85
    92
    95
    =========轉(zhuǎn)成map==========
    數(shù)學(xué):95
    語文:85
    英語:92
    =========字符串分隔符連接==========
    (語文,數(shù)學(xué),英語)
    

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

    //寫法一
    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同時(shí)使用了終止操作符,大家都會(huì)想到終止操作不是只能用一次就終止了么?其實(shí)forEach不僅僅是Stream中得操作符還是各種集合中得一個(gè)語法糖。

匹配、聚合操作

  • allMatch:匹配操作,接收一個(gè) Predicate 函數(shù),當(dāng)流中每個(gè)元素都符合該斷言時(shí)才返回true,否則返回false
    noneMatch:匹配操作,接收一個(gè) Predicate 函數(shù),當(dāng)流中每個(gè)元素都不符合該斷言時(shí)才返回true,否則返回false
    anyMatch:匹配操作,接收一個(gè) Predicate 函數(shù),只要流中有一個(gè)元素滿足該斷言則返回true,否則返回false
    findFirst:查找操作,返回流中第一個(gè)元素
    findAny:查找操作,返回流中的任意元素
    count:聚合操作,返回流中元素的總個(gè)數(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(),歸約操作,把整個(gè)數(shù)據(jù)流的值歸約為一個(gè)值(比如對(duì)所有元素求和,乘啊等)。(如:count、max、min操作的底層就是運(yùn)用了歸約操作)

    Optional reduce(BinaryOperator accumulator):

    第一次執(zhí)行時(shí),accumulator函數(shù)的第一個(gè)參數(shù)為流中的第一個(gè)元素,第二個(gè)參數(shù)為流中元素的第二個(gè)元素;第二次執(zhí)行時(shí),第一個(gè)參數(shù)為第一次函數(shù)執(zhí)行的結(jié)果,第二個(gè)參數(shù)為流中的第三個(gè)元素;依次類推。

    T reduce(T identity, BinaryOperator accumulator):

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

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

    在串行流(stream)中,該方法跟第二個(gè)方法一樣,即第三個(gè)參數(shù)combiner不會(huì)起作用。在并行流(parallelStream)中,我們知道流被fork join出多個(gè)線程進(jìn)行執(zhí)行,此時(shí)每個(gè)線程的執(zhí)行流程就跟第二個(gè)方法reduce(identity,accumulator)一樣,而第三個(gè)參數(shù)combiner函數(shù),則是將每個(gè)線程的執(zhí)行結(jié)果當(dāng)成一個(gè)新的流,然后使用第一個(gè)方法reduce(accumulator)流程進(jìn)行歸約。

    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ù)學(xué)", 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();
    

    前三個(gè),是調(diào)用的stream的toArray的函數(shù),后面的兩個(gè),是直接調(diào)用的List接口的toArray函數(shù)。

總結(jié)

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

注意

  • 集合講的是數(shù)據(jù),流講的計(jì)算。
  • Stream本身不會(huì)存儲(chǔ)元素。
  • Stream不會(huì)改變?cè)磳?duì)象,但它會(huì)返回一個(gè)持有結(jié)果的新Stream。
  • Stream操作是延遲執(zhí)行的。這就意味著他們會(huì)等到需要結(jié)果的時(shí)候才執(zhí)行。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 轉(zhuǎn)自: Java 8 中的 Streams API 詳解 為什么需要 Stream Stream 作為 Java ...
    普度眾生的面癱青年閱讀 2,932評(píng)論 0 11
  • 了解Stream ? Java8中有兩個(gè)最為重要的改變,一個(gè)是Lambda表達(dá)式,另一個(gè)就是Stream AP...
    龍歷旗閱讀 3,350評(píng)論 3 4
  • Java 8自Java 5(發(fā)行于2004)以來最具革命性的版本。Java 8 為Java語言、編譯器、類庫、開發(fā)...
    誰在烽煙彼岸閱讀 909評(píng)論 0 4
  • Java 8自Java 5(發(fā)行于2004)以來最具革命性的版本。Java 8 為Java語言、編譯器、類庫、開發(fā)...
    huoyl0410閱讀 661評(píng)論 1 2
  • 1. 什么是λ表達(dá)式 λ表達(dá)式本質(zhì)上是一個(gè)匿名方法。讓我們來看下面這個(gè)例子: public int add(int...
    黎景陽閱讀 2,180評(píng)論 1 3