真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

java8的Stream特性是什么

本篇內(nèi)容介紹了“java8的Stream特性是什么”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)建站服務項目包括新干網(wǎng)站建設(shè)、新干網(wǎng)站制作、新干網(wǎng)頁制作以及新干網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,新干網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到新干省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!

java.util.Stream 表示能應用在一組元素上一次執(zhí)行的操作序列。Stream 操作分為中間操作或者最終操作兩種,最終操作返回一特定類型的計算結(jié)果,而中間操作返回Stream本身,這樣就可以將多個操作依次串起來。Stream 的創(chuàng)建需要指定一個數(shù)據(jù)源,比如 java.util.Collection的子類,List或者Set, Map不支持。Stream的操作可以串行stream()執(zhí)行或者并行parallelStream()執(zhí)行。

java8的Stream特性是什么

java8的Stream特性是什么

一、簡介

     java8新添加了一個特性:流Stream。Stream讓開發(fā)者能夠以一種聲明的方式處理數(shù)據(jù)源(集合、數(shù)組等),它專注于對數(shù)據(jù)源進行各種高效的聚合操作(aggregate operation)和大批量數(shù)據(jù)操作(bulk data operation)。

    Stream API將處理的數(shù)據(jù)源看做一種Stream(流),Stream(流)在Pipeline(管道)中傳輸和運算,支持的運算包含篩選、排序、聚合等,當?shù)竭_終點后便得到最終的處理結(jié)果。

幾個關(guān)鍵概念

  1. 元素Stream是一個來自數(shù)據(jù)源的元素隊列,Stream本身并不存儲元素。

  2. 數(shù)據(jù)源(即Stream的來源)包含集合、數(shù)組、I/O channel、generator(發(fā)生器)等。

  3. 聚合操作類似SQL中的filter、map、find、match、sorted等操作

  4. 管道運算Stream在Pipeline中運算后返回Stream對象本身,這樣多個操作串聯(lián)成一個Pipeline,并形成fluent風格的代碼。這種方式可以優(yōu)化操作,如延遲執(zhí)行(laziness)和短路( short-circuiting)。

  5. 內(nèi)部迭代不同于java8以前對集合的遍歷方式(外部迭代),Stream API采用訪問者模式(Visitor)實現(xiàn)了內(nèi)部迭代。

  6. 并行運算Stream API支持串行(stream() )或并行(parallelStream() )的兩種操作方式。

Stream API的特點:

  1. Stream API的使用和同樣是java8新特性的 lambda表達式 密不可分,可以大大提高編碼效率和代碼可讀性。

  2. Stream API提供串行和并行兩種操作,其中并行操作能發(fā)揮多核處理器的優(yōu)勢,使用fork/join的方式進行并行操作以提高運行速度。

  3. Stream API進行并行操作無需編寫多線程代碼即可寫出高效的并發(fā)程序,且通??杀苊舛嗑€程代碼出錯的問題。

二、簡單示例

    我們來看一個簡單的示例,統(tǒng)計整數(shù)數(shù)組中正數(shù)的個數(shù):

  1. 在java8之前:

    public static void main(String[] args)
    {  
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
        
        long count = 0;
        
        for(Integer number: numbers)
        {
            if(number > 0)
            {
                count++;
            }
        }
        
        System.out.println("Positive count: " + count);
    }
  1. 在java8之后:

    public static void main(String[] args)
    {  
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
      
        long count = numbers.parallelStream().filter(i -> i>0).count();
        
        System.out.println("Positive count: " + count);
    }

可以看到,上例中,使用filter()方法對數(shù)組進行了過濾,使用count()方法對過濾后的數(shù)組進行了大小統(tǒng)計,且使parallelStream()方法為集合創(chuàng)建了并行流,自動采用并行運算提高速度。在更復雜的場景,還可以用forEach()、map()、limit()、sorted()、collect()等方法進行進一步的流運算。

三、典型接口詳解

    本節(jié)以典型場景為例,列出Stream API常用接口的用法,并附上相應代碼。
    需要說明的是,Stream API中存在很多方法重載,同名方法本文中可能僅列舉一個,請讀者注意~

3.1  Stream的生成

    java8 Stream API支持串行或并行的方式,可以簡單看下jdk1.8 Collection接口的源碼(注釋只截取部分):

    /**
     * @return a sequential {@code Stream} over the elements in this collection
     * @since 1.8
     */
    default Stream stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    /**
     * @return a possibly parallel {@code Stream} over the elements in this collection
     * @since 1.8
     */
    default Stream parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }

可以看出,在集合類的接口(Collection)中,分別用兩種方式來生成:

        1. 串行流 : stream()
        2. 并行流 : parallelStream()

應該注意的是,使用parallelStream()生成并行流后,對集合元素的遍歷是無序的。

3.2  forEach()方法

    簡單看下forEach()方法的源碼(注釋只截取部分):

    /**
     * Performs an action for each element of this stream.
     */
    void forEach(Consumer action);

forEach()方法的參數(shù)為一個Consumer(消費函數(shù),一個函數(shù)式接口)對象,forEach()方法用來迭代流中的每一個數(shù)據(jù),例如:

    public static void main(String[] args)
    {  
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
        
        numbers.stream().forEach(n ->  System.out.println("List element: " + n));
    }

上例中,對數(shù)組的每個元素進行串行遍歷,并打印每個元素的值。

ps:
    集合的頂層接口Iterable中也投forEach方法,可以直接對數(shù)組元素進行遍歷:

    public static void main(String[] args)
    {  
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
        
        numbers.forEach(n ->  System.out.println("List element: " + n));
    }

當然用Strem API的好處不僅僅是遍歷~~~

3.3  map()方法

    簡單看下map()方法的源碼(注釋只截取部分):

    /**
     * Returns a stream consisting of the results of applying the given function to the elements of this stream.
     * @param  The element type of the new stream
     * @param mapper a non-interfering,
     *               stateless
     *               function to apply to each element
     * @return the new stream
     */
     Stream map(Function mapper);

map()方法的參數(shù)為Function(函數(shù)式接口)對象,map()方法將流中的所有元素用Function對象進行運算,生成新的流對象(流的元素類型可能改變)。舉例如下:

    public static void main(String[] args)
    {  
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
        
        numbers.stream().map( n -> Math.abs(n)).forEach(n ->  System.out.println("Element abs: " + n));
    }

上例中,用map()方法計算了所有數(shù)組元素的絕對值并生成了一個新的流,然后再用forEach()遍歷打印。

3.4  flatMap()方法

    簡單看下flatMap()方法的源碼(省略注釋):

  Stream flatMap(Function> mapper);

顯然,跟map()方法不同的是,F(xiàn)unction函數(shù)的返回值類型是Stream類型,而不是R類型,即Function函數(shù)返回一個Stream流,這樣flatMap()能夠?qū)⒁粋€二維的集合映射成一個一維的集合,比map()方法擁有更高的映射深度(此處可能有一點繞,可結(jié)合例子理解),作個簡單示例如下:

有一個字符串數(shù)組:

List list = Arrays.asList("1 2", "3 4", "5 6");

其有三個元素,每個元素有兩個數(shù)組并用空格隔開,如果每個元素以空格分割成2個元素,并遍歷打印這6個元素,

用flatMap()方法如下:

list.stream().flatMap(item -> Arrays.stream(item.split(" "))).forEach(System.out::println);

而用map()方法:

 list.stream().map(item -> Arrays.stream(item.split(" "))).forEach(n ->n.forEach(System.out::println));

可見,用map()方法,返回了一個“流中流”,需要在每個Stream元素遍歷時,再加一層forEach進行遍歷。

3.5  filter()方法

    簡單看下filter()方法的源碼(注釋只截取部分):

    /**
     * Returns a stream consisting of the elements of this stream that match the given predicate.
     *
     * 

This is an intermediate operation.      *      * @param predicate a non-interfering,      *                  stateless      *                  predicate to apply to each element to determine if it  should be included      * @return the new stream      */     Stream filter(Predicate predicate);

filter()方法的參數(shù)為Predicate(函數(shù)式接口)對象,再lambda表達式的講解中我們提到過這個接口,一般用它進行過濾。正如第二章中示例:

    public static void main(String[] args)
    {  
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
      
        long count = numbers.parallelStream().filter(i -> i>0).count();
        
        System.out.println("Positive count: " + count);
    }

用filter方法很容易過濾出整數(shù)數(shù)組中的自然數(shù)。

3.6  reduce()方法

    reduce操作又稱為折疊操作,用于將流中的所有值合成一個。reduce()方法的源碼(不提供計算初始值的reduce方法)(省略注釋):

Optional reduce(BinaryOperator accumulator);

reduce()方法參數(shù)為BinaryOperator類型的累加器(它接受兩個類型相同的參數(shù),返回值類型跟參數(shù)類型相同),返回一個Optional對象。
 實際上,Stream API中的mapToInt()方法返回的IntStream接口有類似的 average()、count()、sum()等方法就是做reduce操作,類似的還有mapToLong()、mapToDouble() 方法。當然,我們也可以用reduce()方法來自定義reduce操作。例如我們用reduce()方法來進行整數(shù)數(shù)組求和操作:

    public static void main(String[] args)
    {
        List numbers = Arrays.asList(-1, -2, 0, -1, 4, 5, 1);
        
        Integer total = numbers.stream().reduce((t, n) -> t + n).get();
        
        System.out.println("Total: " + total);
    }

上例中利用reduce()方法結(jié)合lambda表達式輕易的實現(xiàn)了數(shù)組的求和功能。

3.7  collect()方法

    簡單看下collect()方法的源碼(注釋只截取部分):

    /**
     * @param  the type of the result
     * @param  the intermediate accumulation type of the {@code Collector}
     * @param collector the {@code Collector} describing the reduction
     * @return the result of the reduction
     */
     R collect(Collector collector);

collect()方法的參數(shù)為一個java.util.stream.Collector類型對象,可以用java.util.stream.Collectors工具類提供的靜態(tài)方法來生成,Collectors類實現(xiàn)很多的歸約操作,如Collectors.toList()、Collectors.toSet()、Collectors.joining()(joining適用于字符串流)等??匆粋€簡單示例:

    public static void main(String[] args)
    {  
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
        
        List abss = numbers.stream().map( n -> Math.abs(n)).collect(Collectors.toList());
        
        System.out.println("Abs list: " + abss);
    }

上例中,用map()方法生成新的流,再用collect()方法返回原數(shù)組的絕對值數(shù)組。

3.8  summaryStatistics()方法進行數(shù)值統(tǒng)計

    其實summaryStatistics()方法并不是Stream接口的方法,而是Stream API采用mapToInt()、mapToLong()、mapToDouble()三個方法分別生成IntStream 、LongStream 、DoubleStream 三個接口類型的對象,這個方法的參數(shù)分別為3個函數(shù)式接口ToIntFunction、ToLongFunction、ToDoubleFunction,使用時可以用lambda表達式計算返回對應的int、long、double類型即可,簡單看下這三個方法的源碼(省略注釋):

    IntStream mapToInt(ToIntFunction mapper);

    LongStream mapToLong(ToLongFunction mapper);

    DoubleStream mapToDouble(ToDoubleFunction mapper);

IntStream 、LongStream 、DoubleStream 三個接口類型都有一個summaryStatistics()方法,其中,

  1. IntStream 的方法是:

 IntSummaryStatistics summaryStatistics();
  1. LongStream 的方法是:

 LongSummaryStatistics summaryStatistics();
  1. DoubleStream 的方法是:

 DoubleSummaryStatistics summaryStatistics();

在IntSummaryStatistics、LongSummaryStatistics 、DoubleSummaryStatistics 三個接口類型(位于java.util包下)中,都有諸如統(tǒng)計數(shù)量、最大值、最小值、求和、平均值等方法(方法名和返回類型可能不同),利用這些方法我們可以方便的進行數(shù)值統(tǒng)計。以IntSummaryStatistics工具包 為例:

    public static void main(String[] args)
    {
        List numbers = Arrays.asList(-1, -2, 0, 4, 5);
        
        IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
        
        System.out.println("Max : " + stats.getMax());
        System.out.println("Min : " + stats.getMin());
        System.out.println("Sum : " + stats.getSum());
        System.out.println("Average : " + stats.getAverage());
        System.out.println("Count : " + stats.getCount());
    }

3.9  其它方法

    Stream API還有一些其它的方法,比如:
    limit()    獲取指定數(shù)量的流
    sorted()   對流進行排序
    distinct()  去重
    skip()    跳過指定數(shù)量的元素
    peek()   生成一個包含原Stream的所有元素的新Stream,并指定消費函數(shù)
    count()   計算元素數(shù)量
    ......

四、注意事項

Stream中的操作從概念上講分為中間操作和終端操作

要理解中間操作和終端操作的概念,防止埋坑~

14個常用Stream:

1. forEach 循環(huán)

@Test
public void forEach(){
    // 你不鳥我,我也不鳥你
    List list = Arrays.asList("you", "don't", "bird", "me", ",", 
                                       "I", "don't", "bird", "you");

    // 方式一:JDK1.8之前的循環(huán)方式
    for (String item: list) {
        System.out.println(item);
    }

    // 方式二:使用Stream的forEach方法
    // void forEach(Consumer action)
    list.stream().forEach(item -> System.out.println(item));

    // 方式三:方式二的簡化方式
    // 由于方法引用也屬于函數(shù)式接口,所以方式二Lambda表達式也可以使用方法引用來代替
    // 此種方式就是方式一、方式二的簡寫形式
    list.stream().forEach(System.out::println);
}

2. filter 過濾

public class User {
    private Long id;
    private String phone;
    private Integer age;

    public User(){}
    public User(Long id, String username, Integer age) {
        this.id = id;
        this.username = username;
        this.age = age;
    }
    // Getter & Setter & toString
}


@Test
public void filter(){
    List users = Arrays.asList(
            new User(1L, "mengday", 28),
            new User(2L, "guoguo", 18),
            new User(3L, "liangliang", 17)
    );

    // Stream filter(Predicate predicate);
    users.stream().filter(user -> user.getAge() > 18).forEach(System.out::println);
}

3. map 映射

@Test
public void map(){
    List list = Arrays.asList("how", "are", "you", "how", "old", "are", "you", "?");
    //  Stream map(Function mapper);
    list.stream().map(item -> item.toUpperCase()).forEach(System.out::println);
}

4. flatMap

@Test
public void flatMap(){
    List a = Arrays.asList(1, 2, 3);
    List b = Arrays.asList(4, 5, 6);

    //  Stream flatMap(Function> mapper)
    List> collect = Stream.of(a, b).collect(Collectors.toList());
    // [[1, 2, 3], [4, 5, 6]] 
    System.out.println(collect);

    // 將多個集合中的元素合并成一個集合
    List mergeList = Stream.of(a, b).flatMap(list -> list.stream()).collect(Collectors.toList());
    // [1, 2, 3, 4, 5, 6]
    System.out.println(mergeList);

    // 通過Builder模式來構(gòu)建
    Stream stream = Stream.builder().add("hello").add("hi").add("byebye").build();
}

5. sorted 排序

@Test
public void sort(){
    List list = Arrays.asList("c", "e", "a", "d", "b");
    // Stream sorted(Comparator comparator);
    // int compare(T o1, T o2);
    list.stream().sorted((s1, s2) -> s1.compareTo(s2)).forEach(System.out::println);
}

6. distinct 去重復

@Test
public void distinct(){
    // 知之為知之,不知為不知
    Stream stream = Stream.of("know", "is", "know", "noknow", "is", "noknow");
    stream.distinct().forEach(System.out::println); // know is noknow
}

7. count 總數(shù)量

@Test
public void count(){
    Stream stream = Stream.of("know", "is", "know", "noknow", "is", "noknow");
    long count = stream.count();
    System.out.println(count);
}

8. min、max

@Test
public void min(){
    List list = Arrays.asList("1", "2", "3", "4", "5");
    // Optional min(Comparator comparator);
    Optional optional = list.stream().min((a, b) -> a.compareTo(b));
    String value = optional.get();
    System.out.println(value);
}

9. skip、limit

@Test
public void skip(){
    List list = Arrays.asList("a", "b", "c", "d", "e");
    // Stream skip(long n)
    list.stream().skip(2).forEach(System.out::println);  // c、d、e
}

@Test
public void limit(){
    List list = Arrays.asList("a", "b", "c", "d", "e");
    list.stream().skip(2).limit(2).forEach(System.out::println);    // c、d
}

10. collect

@Test
public void collect(){
    List list = Arrays.asList("a", "b", "c", "d", "e");
    // Stream -> Collection
    List collect = list.stream().collect(Collectors.toList());

    // Stream -> Object[]
    Object[] objects = list.stream().toArray();
}

11. concat

@Test
public void concat(){
    List list = Arrays.asList("a", "b");
    List list2 = Arrays.asList("c", "d");
    Stream concatStream = Stream.concat(list.stream(), list2.stream());
    concatStream.forEach(System.out::println);
}

12. anyMatch、allMatch

@Test
public void match(){
    // 你給我站住
    List list = Arrays.asList("you", "give", "me", "stop");
    // boolean anyMatch(Predicate predicate);
    // parallelStream可以并行計算,速度比stream更快
    boolean result = list.parallelStream().anyMatch(item -> item.equals("me"));
    System.out.println(result);
}

/**
* anyMatch偽代碼
 * 如果集合中有一個元素滿足條件就返回true
 * @return
 */
public  boolean anyMatch() {
    List list = Arrays.asList("you", "give", "me", "stop");
    for (String item : list) {
        if (item.equals("me")) {
            return true;
        }
    }

        return false;
    }

13. reduce 歸納

@Test
public void reduce(){
    Stream stream = Stream.of("you", "give", "me", "stop");
    // Optional reduce(BinaryOperator accumulator);
    Optional optional = stream.reduce((before, after) -> before + "," + after);
    optional.ifPresent(System.out::println);    // you,give,me,stop
}

BigDecimal求和

public static void main(String[] args) {
    List list = Arrays.asList(
            new BigDecimal("11.11"),
            new BigDecimal("22.22"),
            new BigDecimal("33.33")
    );
    // 66.66
    BigDecimal sum = list.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
    System.out.println(sum);
}

14. findFirst、findAny

@Test
public void findFirst(){
    Stream stream = Stream.of("you", "give", "me", "stop");
    String value = stream.findFirst().get();
    System.out.println(value);
}

@Test
public void findAny(){
    Stream stream = Stream.of("you", "give", "me", "stop");
    String value2 = stream.findAny().get();
    System.out.println(value2);
}

“java8的Stream特性是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!


當前題目:java8的Stream特性是什么
本文網(wǎng)址:http://weahome.cn/article/jppejj.html

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部