1. 程式人生 > >Java 8 Stream API具體解釋

Java 8 Stream API具體解釋

介紹 lis 控制臺輸出 output 排序。 case 編程效率 func 遍歷

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並行方式來拆分任務和加速處理過程。

通常編寫並行代碼非常難並且easy出錯。但使用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));

Java 8 Stream API具體解釋