最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java8新特性 StreamAPI實例詳解

 更新時間:2022年11月02日 11:48:28   作者:我一定有辦法  
這篇文章主要為大家介紹了Java8新特性 StreamAPI實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

Stream結果收集

面試官:說說你常用的StreamAPI。

結果收集到集合中

    public static void main(String[] args){
        // Stream<String> stream = Stream.of("aa", "bb", "cc");
        List<String> list = Stream.of("aa", "bb", "cc","aa")
                .collect(Collectors.toList());
        System.out.println(list);
        // 收集到 Set集合中
        Set<String> set = Stream.of("aa", "bb", "cc", "aa")
                .collect(Collectors.toSet());
        System.out.println(set);
        // 如果需要獲取的類型為具體的實現(xiàn),比如:ArrayList HashSet
        ArrayList<String> arrayList = Stream.of("aa", "bb", "cc", "aa")
                //.collect(Collectors.toCollection(() -> new ArrayList<>()));
                .collect(Collectors.toCollection(ArrayList::new));
        System.out.println(arrayList);
        HashSet<String> hashSet = Stream.of("aa", "bb", "cc", "aa")
                .collect(Collectors.toCollection(HashSet::new));
        System.out.println(hashSet);
    }

輸出:

[aa, bb, cc, aa]
[aa, bb, cc]
[aa, bb, cc, aa]
[aa, bb, cc]

結果收集到數(shù)組中

Stream中提供了toArray方法來將結果放到一個數(shù)組中,返回值類型是Object[],如果我們要指定返回的類型,那么可以使用另一個重載的toArray(IntFunction f)方法。

    public static void main(String[] args){
        Object[] objects = Stream.of("aa", "bb", "cc", "aa")
                .toArray(); // 返回的數(shù)組中的元素是 Object類型
        System.out.println(Arrays.toString(objects));
        // 如果我們需要指定返回的數(shù)組中的元素類型
        String[] strings = Stream.of("aa", "bb", "cc", "aa")
                .toArray(String[]::new);
        System.out.println(Arrays.toString(strings));
    }

對流中的數(shù)據(jù)做聚合計算

當我們使用Stream流處理數(shù)據(jù)后,可以像數(shù)據(jù)庫的聚合函數(shù)一樣對某個字段進行操作,比如獲得最大值,最小值,求和,平均值,統(tǒng)計數(shù)量。

    public static void main(String[] args) {
        // 獲取年齡的最大值
        Optional<Person> maxAge = Stream.of(
                new Person("張三", 18)
                , new Person("李四", 22)
                , new Person("張三", 13)
                , new Person("王五", 15)
                , new Person("張三", 19)
        ).collect(Collectors.maxBy((p1, p2) -> p1.getAge() - p2.getAge()));
        System.out.println("最大年齡:" + maxAge.get());
        // 獲取年齡的最小值
        Optional<Person> minAge = Stream.of(
                new Person("張三", 18)
                , new Person("李四", 22)
                , new Person("張三", 13)
                , new Person("王五", 15)
                , new Person("張三", 19)
        ).collect(Collectors.minBy((p1, p2) -> p1.getAge() - p2.getAge()));
        System.out.println("最新年齡:" + minAge.get());
        // 求所有人的年齡之和
        Integer sumAge = Stream.of(
                new Person("張三", 18)
                , new Person("李四", 22)
                , new Person("張三", 13)
                , new Person("王五", 15)
                , new Person("張三", 19)
        )
                //.collect(Collectors.summingInt(s -> s.getAge()))
                .collect(Collectors.summingInt(Person::getAge))
                ;
        System.out.println("年齡總和:" + sumAge);
        // 年齡的平均值
        Double avgAge = Stream.of(
                new Person("張三", 18)
                , new Person("李四", 22)
                , new Person("張三", 13)
                , new Person("王五", 15)
                , new Person("張三", 19)
        ).collect(Collectors.averagingInt(Person::getAge));
        System.out.println("年齡的平均值:" + avgAge);
        // 統(tǒng)計數(shù)量
        Long count = Stream.of(
                new Person("張三", 18)
                , new Person("李四", 22)
                , new Person("張三", 13)
                , new Person("王五", 15)
                , new Person("張三", 19)
        ).filter(p->p.getAge() > 18)
                .collect(Collectors.counting());
        System.out.println("滿足條件的記錄數(shù):" + count);
    }

對流中數(shù)據(jù)做分組操作

當我們使用Stream流處理數(shù)據(jù)后,可以根據(jù)某個屬性將數(shù)據(jù)分組。

    public static void main(String[] args){
        // 根據(jù)賬號對數(shù)據(jù)進行分組
        Map<String, List<Person>> map1 = Stream.of(
                new Person("張三", 18, 175)
                , new Person("李四", 22, 177)
                , new Person("張三", 14, 165)
                , new Person("李四", 15, 166)
                , new Person("張三", 19, 182)
        ).collect(Collectors.groupingBy(Person::getName));
        map1.forEach((k,v)-> System.out.println("k=" + k +"\t"+ "v=" + v));
        System.out.println("-----------");
        // 根據(jù)年齡分組 如果大于等于18 成年否則未成年
        Map<String, List<Person>> map2 = Stream.of(
                new Person("張三", 18, 175)
                , new Person("李四", 22, 177)
                , new Person("張三", 14, 165)
                , new Person("李四", 15, 166)
                , new Person("張三", 19, 182)
        ).collect(Collectors.groupingBy(p -> p.getAge() >= 18 ? "成年" : "未成年"));
        map2.forEach((k,v)-> System.out.println("k=" + k +"\t"+ "v=" + v));
    }

輸出結果:

k=李四    v=[Person{name='李四', age=22, height=177}, Person{name='李四', age=15, height=166}]
k=張三    v=[Person{name='張三', age=18, height=175}, Person{name='張三', age=14, height=165}, Person{name='張三', age=19, height=182}]
-----------
k=未成年    v=[Person{name='張三', age=14, height=165}, Person{name='李四', age=15, height=166}]
k=成年    v=[Person{name='張三', age=18, height=175}, Person{name='李四', age=22, height=177}, Person{name='張三', age=19, height=182}]

多級分組: 先根據(jù)name分組然后根據(jù)年齡分組。

    public static void main(String[] args){
        // 先根據(jù)name分組,然后根據(jù)age(成年和未成年)分組
        Map<String,Map<Object,List<Person>>> map =  Stream.of(
                new Person("張三", 18, 175)
                , new Person("李四", 22, 177)
                , new Person("張三", 14, 165)
                , new Person("李四", 15, 166)
                , new Person("張三", 19, 182)
        ).collect(Collectors.groupingBy(
                Person::getName
                ,Collectors.groupingBy(p->p.getAge()>=18?"成年":"未成年"
                )
        ));
        map.forEach((k,v)->{
            System.out.println(k);
            v.forEach((k1,v1)->{
                System.out.println("\t"+k1 + "=" + v1);
            });
        });
    }

輸出結果:

李四
    未成年=[Person{name='李四', age=15, height=166}]
    成年=[Person{name='李四', age=22, height=177}]
張三
    未成年=[Person{name='張三', age=14, height=165}]
    成年=[Person{name='張三', age=18, height=175}, Person{name='張三', age=19, height=182}]

對流中的數(shù)據(jù)做分區(qū)操作

Collectors.partitioningBy會根據(jù)值是否為true,把集合中的數(shù)據(jù)分割為兩個列表,一個true列表,一個false列表。

    public static void main(String[] args){
        Map<Boolean, List<Person>> map = Stream.of(
                new Person("張三", 18, 175)
                , new Person("李四", 22, 177)
                , new Person("張三", 14, 165)
                , new Person("李四", 15, 166)
                , new Person("張三", 19, 182)
        ).collect(Collectors.partitioningBy(p -> p.getAge() > 18));
        map.forEach((k,v)-> System.out.println(k+"\t" + v));
    }

輸出結果:

false    [Person{name='張三', age=18, height=175}, Person{name='張三', age=14, height=165}, Person{name='李四', age=15, height=166}]
true    [Person{name='李四', age=22, height=177}, Person{name='張三', age=19, height=182}]

對流中的數(shù)據(jù)做拼接

Collectors.joining會根據(jù)指定的連接符,將所有的元素連接成一個字符串。

    public static void main(String[] args){
        String s1 = Stream.of(
                new Person("張三", 18, 175)
                , new Person("李四", 22, 177)
                , new Person("張三", 14, 165)
                , new Person("李四", 15, 166)
                , new Person("張三", 19, 182)
        ).map(Person::getName)
                .collect(Collectors.joining());
        // 張三李四張三李四張三
        System.out.println(s1);
        String s2 = Stream.of(
                new Person("張三", 18, 175)
                , new Person("李四", 22, 177)
                , new Person("張三", 14, 165)
                , new Person("李四", 15, 166)
                , new Person("張三", 19, 182)
        ).map(Person::getName)
                .collect(Collectors.joining("_"));
        // 張三_李四_張三_李四_張三
        System.out.println(s2);
        String s3 = Stream.of(
                new Person("張三", 18, 175)
                , new Person("李四", 22, 177)
                , new Person("張三", 14, 165)
                , new Person("李四", 15, 166)
                , new Person("張三", 19, 182)
        ).map(Person::getName)
                .collect(Collectors.joining("_", "###", "$$$"));
        // ###張三_李四_張三_李四_張三$$$
        System.out.println(s3);
    }

并行的Stream流

串行的Stream流

我們前面使用的Stream流都是串行,也就是在一個線程上面執(zhí)行。

并行流

parallelStream其實就是一個并行執(zhí)行的流,它通過默認的ForkJoinPool,可以提高多線程任務的速度。

獲取并行流

我們可以通過兩種方式來獲取并行流。

  • 通過List接口中的parallelStream方法來獲取
  • 通過已有的串行流轉換為并行流(parallel)
    public static void main(String[] args){
        List<Integer> list = new ArrayList<>();
        // 通過List 接口 直接獲取并行流
        Stream<Integer> integerStream = list.parallelStream();
        // 將已有的串行流轉換為并行流
        Stream<Integer> parallel = Stream.of(1, 2, 3).parallel();
    }

并行流操作

    public static void main(String[] args){
        Stream.of(1,4,2,6,1,5,9)
                .parallel() // 將流轉換為并發(fā)流,Stream處理的時候就會通過多線程處理
                .filter(s->{
                    System.out.println(Thread.currentThread() + " s=" +s);
                    return s > 2;
                }).count();
    }

并行流和串行流對比

我們通過for循環(huán),串行Stream流,并行Stream流來對500000000億個數(shù)字求和。來看消耗時間。

public class Test {
    private static long times = 500000000;
    private  long start;
    @Before
    public void befor(){
        start = System.currentTimeMillis();
    }
    @After
    public void end(){
        long end = System.currentTimeMillis();
        System.out.println("消耗時間:" + (end - start));
    }
    /**
     * 普通for循環(huán) 消耗時間:138
     */
    @Test
    public void test01(){
        System.out.println("普通for循環(huán):");
        long res = 0;
        for (int i = 0; i < times; i++) {
            res += i;
        }
    }
    /**
     * 串行流處理
     *   消耗時間:203
     */
    @Test
    public void test02(){
        System.out.println("串行流:serialStream");
        LongStream.rangeClosed(0,times)
                .reduce(0,Long::sum);
    }
    /**
     * 并行流處理 消耗時間:84
     */
    @Test
    public void test03(){
        LongStream.rangeClosed(0,times)
                .parallel()
                .reduce(0,Long::sum);
    }
}

通過案例我們可以看到parallelStream的效率是最高的。

Stream并行處理的過程會分而治之,也就是將一個大的任務切分成了多個小任務,這表示每個任務都是一個線程操作。

線程安全問題

在多線程的處理下,肯定會出現(xiàn)數(shù)據(jù)安全問題。如下:

    @Test
    public void test(){
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list.add(i);
        }
        System.out.println(list.size());
        List<Integer> listNew = new ArrayList<>();
        // 使用并行流來向集合中添加數(shù)據(jù)
        list.parallelStream()
                //.forEach(s->listNew.add(s));
                .forEach(listNew::add);
        System.out.println(listNew.size());// 839
    }

針對這個問題,我們的解決方案有哪些呢?

  • 加同步鎖
  • 使用線程安全的容器
  • 通過Stream中的toArray/collect操作

以上就是Java8新特性 StreamAPI實例詳解的詳細內容,更多關于Java8新特性 StreamAPI的資料請關注腳本之家其它相關文章!

相關文章

  • Java多線程產生死鎖的必要條件

    Java多線程產生死鎖的必要條件

    今天小編就為大家分享一篇關于Java多線程產生死鎖的必要條件,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 使用Autowired為什么會被IDEA警告最佳修改方法

    使用Autowired為什么會被IDEA警告最佳修改方法

    這篇文章主要介紹了使用Autowired為什么會被IDEA警告,應該怎么修改最佳,除了使用@Autowired以外,我們其實也有幾種好用的方式,使用@Resource替代@Autiwired方法是其中一種,只需要改變一個注解,這里就不展示了,需要的朋友可以參考下
    2023-02-02
  • Spring解決依賴版本不一致報錯問題

    Spring解決依賴版本不一致報錯問題

    許多同學經(jīng)常會遇到依賴版本不一致導致代碼報錯,所以這篇文章就給大家詳細介紹一下Spring解決依賴版本不一致報錯問題,需要的朋友跟著小編一起來看看吧
    2023-07-07
  • 關于ResponseEntity類和HttpEntity及跨平臺路徑問題

    關于ResponseEntity類和HttpEntity及跨平臺路徑問題

    這篇文章主要介紹了關于ResponseEntity類和HttpEntity及跨平臺路徑問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java 是如何讀取和寫入瀏覽器Cookies的實例詳解

    Java 是如何讀取和寫入瀏覽器Cookies的實例詳解

    這篇文章主要介紹了Java 是如何讀取和寫入瀏覽器Cookies的實例的相關資料,需要的朋友可以參考下
    2016-09-09
  • IDEA自定義Maven archetype的方法步驟

    IDEA自定義Maven archetype的方法步驟

    在創(chuàng)建Maven的項目時我們發(fā)現(xiàn)了一個很不方便的問題,就是每次創(chuàng)建Maven的工程的時候,都需要選擇一個骨架,本文主要介紹了IDEA自定義Maven archetype的方法步驟,感興趣的可以了解一下
    2022-03-03
  • SpringBoot中Get請求和POST請求接收參數(shù)示例詳解

    SpringBoot中Get請求和POST請求接收參數(shù)示例詳解

    文章詳細介紹了SpringBoot中Get請求和POST請求的參數(shù)接收方式,包括方法形參接收參數(shù)、實體類接收參數(shù)、HttpServletRequest接收參數(shù)、@PathVariable接收參數(shù)、數(shù)組參數(shù)接收、集合參數(shù)接收、Map接收參數(shù)以及通過@RequestBody接收JSON格式的參數(shù),感興趣的朋友一起看看吧
    2024-12-12
  • 在SpringBoot中實現(xiàn)線程池并行處理任務的方法詳解

    在SpringBoot中實現(xiàn)線程池并行處理任務的方法詳解

    在使用Spring Boot開發(fā)應用程序時,我們經(jīng)常需要處理一些耗時的任務,例如網(wǎng)絡請求、數(shù)據(jù)庫操作或者其他需要花費一定時間的計算任務,本文將介紹如何在Spring Boot中使用線程池來實現(xiàn)任務的并行處理
    2023-06-06
  • java編程小白進階包的作用詳解

    java編程小白進階包的作用詳解

    這篇文章主要為大家介紹了java編程中包的作用詳解,文中通過示例分析方便大家更容易理解包的作用,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • 在Java中String和Date、Timestamp之間的轉換

    在Java中String和Date、Timestamp之間的轉換

    這篇文章主要介紹了在Java中String和Date、Timestamp之間的轉換 的相關資料,需要的朋友可以參考下
    2015-12-12

最新評論

乌拉特前旗| 郯城县| 玉溪市| 洪泽县| 龙川县| 阿城市| 常熟市| 仁怀市| 正镶白旗| 东源县| 慈利县| 高邑县| 浙江省| 柯坪县| 苏尼特右旗| 龙岩市| 古丈县| 富民县| 高雄市| 出国| 大兴区| 广河县| 京山县| 麻城市| 视频| 长阳| 西城区| 泾源县| 塔城市| 嘉峪关市| 邵东县| 平阴县| 皮山县| 龙海市| 子洲县| 上蔡县| 繁昌县| 灵石县| 马尔康县| 祁东县| 蒲江县|