Java 8 Stream API詳解--轉


原文地址:http://blog.csdn.net/chszs/article/details/47038607

Java 8 Stream API詳解

一、Stream API介紹

Java 8引入了全新的Stream API,此Stream與Java I/O包里的InputStream和OutputStream是完全不同的概念,它不同於StAX對XML解析的Stream,也不同於Amazon Kinesis對大數據實時處理的Stream。Stream API更像具有Iterable的集合類,但行為和集合類又有所不同,它是對集合對象功能的增強,專注於對集合對象進行各種非常便捷、高效的聚合操作或大批量數據操作。

Stream API引入的目的在於彌補Java函數式編程的缺陷。對於很多支持函數式編程的語言,map()、reduce()基本上都內置到語言的標准庫中了,不過,Java 8的Stream API總體來講仍然是非常完善和強大,足以用很少的代碼完成許多復雜的功能。

Java 8的Stream API充分利用Lambda表達式的特性,極大的提高編程效率和程序可讀性。同時它提供串行和並行兩種模式進行匯聚操作,並發模式能夠充分利用多核處理器的優勢,使用fork/join並行方式來拆分任務和加速處理過程。通常編寫並行代碼很難而且容易出錯,但使用Stream API無需編寫一行多線程的代碼,就可以很方便地寫出高性能的並發程序。

在Stream API中,一個流基本上代表一個元素序列,Stream API提供了豐富的操作函數來計算這些元素。以前我們在開發業務應用時,通常很多操作的實現是這樣做的:我們使用循環對集合做遍歷,針對集合中的元素實現各種操作,定義各種變量來實現目的,這樣我們就得到了一大堆丑陋的順序代碼。

如果我們使用Stream API做同樣的事情,使用Lambda表達式和其它函數進行抽象,可以使得代碼更易於理解、更為干凈。有了這些抽象,還可以做一些優化,比如實現並行等。

二、Stream API實例

1. 使用IntStream移除常規的循環

比如在控制台輸出0~9的例子:
注意需import java.util.stream.IntStream;

IntStream.range(0, 10).forEach(value -> System.out.println(value));

2. 計算列表中的元素數

注意需

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

List<Integer> list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
System.out.println(list.stream().count());

3. 計算列表中元素的平均數

Double avarage = list.stream().collect(Collectors.averagingInt(item -> item));

4. 對列表元素進行統計

List<Integer> list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
IntSummaryStatistics iss = list.stream().collect(Collectors.summarizingInt(value -> value));
System.out.println(iss);

​ 
輸出結果:

IntSummaryStatistics{count=99, sum=4950, min=1, average=50.000000, max=99}

5. 根據List創建Map

List<Integer> list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
Map<Integer, Integer> map = list.stream().collect(Collectors.toMap(p -> p, q->q*3));
System.out.println(map);

輸出結果:

{1=3, 2=6, 3=9, 4=12, 5=15, 6=18, 7=21, 8=24, 9=27, 10=30, 11=33, 12=36, 13=39, 14=42, 15=45, 16=48, 17=51, 18=54, 19=57, 20=60, 21=63, 22=66, 23=69, 24=72, 25=75, 26=78, 27=81, 28=84, 29=87, 30=90, 31=93, 32=96, 33=99, 34=102, 35=105, 36=108, 37=111, 38=114, 39=117, 40=120, 41=123, 42=126, 43=129, 44=132, 45=135, 46=138, 47=141, 48=144, 49=147, 50=150, 51=153, 52=156, 53=159, 54=162, 55=165, 56=168, 57=171, 58=174, 59=177, 60=180, 61=183, 62=186, 63=189, 64=192, 65=195, 66=198, 67=201, 68=204, 69=207, 70=210, 71=213, 72=216, 73=219, 74=222, 75=225, 76=228, 77=231, 78=234, 79=237, 80=240, 81=243, 82=246, 83=249, 84=252, 85=255, 86=258, 87=261, 88=264, 89=267, 90=270, 91=273, 92=276, 93=279, 94=282, 95=285, 96=288, 97=291, 98=294, 99=297}

6. 求列表元素的最大數

List<Integer> list = new Random().ints(-100,100).limit(250).boxed().collect(Collectors.toList());
Optional<Integer> max = list.stream().reduce(Math::max);
max.ifPresent(value -> System.out.println(value));

7. 從一堆姓名列表中找出以字母“C”開頭的姓名

​String[] names = { "Fred Edwards", "Anna Cox", "Deborah Patterson", "Ruth Torres", "Shawn Powell",
                "Rose Thompson", "Rachel Barnes", "Eugene Ramirez", "Earl Flores", "Janice Reed", "Sarah Miller",
                "Patricia Kelly", "Carl Hall", "Craig Wright", "Martha Phillips", "Thomas Howard", "Steve Martinez",
                "Diana Bailey", "Kathleen Hughes", "Russell Anderson", "Theresa Perry" };
List<String> ls = Arrays.asList(names).stream().filter(s -> s.startsWith("C")).collect(Collectors.toList());
System.out.println(ls.toString());

8. 把所有的姓名大寫、排序,再輸出

String[] names = { "Fred Edwards", "Anna Cox", "Deborah Patterson", "Ruth Torres", "Shawn Powell",
                "Rose Thompson", "Rachel Barnes", "Eugene Ramirez", "Earl Flores", "Janice Reed", "Sarah Miller",
                "Patricia Kelly", "Carl Hall", "Craig Wright", "Martha Phillips", "Thomas Howard", "Steve Martinez",
                "Diana Bailey", "Kathleen Hughes", "Russell Anderson", "Theresa Perry" };
Arrays.asList(names)
         .stream()
         .map(String::toUpperCase)
         .sorted().forEach(System.out::println);

三、更復雜的例子

1. 創建一個Person類

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return name;
    }
}

2. 根據年齡對Person進行分組

Map<Integer, List<Person>> collect = persons.stream().collect(Collectors.groupingBy(Person::getAge));

3. 對所有Person求平均年齡

Double collect = persons.stream().collect(Collectors.averagingInt(Person::getAge));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM