<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    I want to fly higher
    programming Explorer
    posts - 114,comments - 263,trackbacks - 0
        本篇用代碼示例結(jié)合JDk源碼講了Java8引入的工具接口Stream以及新Map接口提供的常用默認(rèn)方法.
        參考:http://winterbe.com/posts/2014/03/16/java-8-tutorial/

        1.Stream示例

    package com.mavsplus.java8.turtorial.streams;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;
    import java.util.UUID;

    /**
     * java.util.Stream使用例子
     * 
     * <pre>
     * java.util.Stream表示了某一種元素的序列,在這些元素上可以進(jìn)行各種操作。Stream操作可以是中間操作,也可以是完結(jié)操作。
     * 完結(jié)操作會(huì)返回一個(gè)某種類型的值,而中間操作會(huì)返回流對(duì)象本身,并且你可以通過多次調(diào)用同一個(gè)流操作方法來將操作結(jié)果串起來。
     * Stream是在一個(gè)源的基礎(chǔ)上創(chuàng)建出來的,例如java.util.Collection中的list或者set(map不能作為Stream的源)。
     * Stream操作往往可以通過順序或者并行兩種方式來執(zhí)行。
     * </pre>
     * 
     * public interface Stream<T> extends BaseStream<T, Stream<T>> {
     * <p>
     * 可以看到Stream是一個(gè)接口,其是1.8引入
     * 
     * <p>
     * Java 8中的Collections類的功能已經(jīng)有所增強(qiáng),你可以之直接通過調(diào)用Collections.stream()或者Collection.
     * parallelStream()方法來創(chuàng)建一個(gè)流對(duì)象
     * 
     * @author landon
     * @since 1.8.0_25
     
    */
    public class StreamUtilExample {

        private List<String> stringList = new ArrayList<>();

        public StreamUtilExample() {
            init();
        }

        private void init() {
            initStringList();
        }

        /**
         * 初始化字符串列表
         
    */
        private void initStringList() {
            stringList.add("zzz1");
            stringList.add("aaa2");
            stringList.add("bbb2");
            stringList.add("fff1");
            stringList.add("fff2");
            stringList.add("aaa1");
            stringList.add("bbb1");
            stringList.add("zzz2");
        }

        /**
         * Filter接受一個(gè)predicate接口類型的變量,并將所有流對(duì)象中的元素進(jìn)行過濾。該操作是一個(gè)中間操作,
         * 因此它允許我們?cè)诜祷亟Y(jié)果的基礎(chǔ)上再進(jìn)行其他的流操作
         * (forEach)。ForEach接受一個(gè)function接口類型的變量,用來執(zhí)行對(duì)每一個(gè)元素的操作
         * 。ForEach是一個(gè)中止操作。它不返回流,所以我們不能再調(diào)用其他的流操作
         
    */
        public void useStreamFilter() {
            // stream()方法是Collection接口的一個(gè)默認(rèn)方法
            
    // Stream<T> filter(Predicate<? super T>
            
    // predicate);filter方法參數(shù)是一個(gè)Predicate函數(shù)式接口并繼續(xù)返回Stream接口
            
    // void forEach(Consumer<? super T> action);foreach方法參數(shù)是一個(gè)Consumer函數(shù)式接口

            
    // 解釋:從字符串序列中過濾出以字符a開頭的字符串并迭代打印輸出
            stringList.stream().filter((s) -> s.startsWith("a")).forEach(System.out::println);
        }

        /**
         * Sorted是一個(gè)中間操作,能夠返回一個(gè)排過序的流對(duì)象的視圖。流對(duì)象中的元素會(huì)默認(rèn)按照自然順序進(jìn)行排序,
         * 除非你自己指定一個(gè)Comparator接口來改變排序規(guī)則.
         * 
         * <p>
         * 一定要記住,sorted只是創(chuàng)建一個(gè)流對(duì)象排序的視圖,而不會(huì)改變?cè)瓉砑现性氐捻樞颉T瓉韘tring集合中的元素順序是沒有改變的
         
    */
        public void useStreamSort() {
            // Stream<T> sorted();返回Stream接口
            
    // 另外還有一個(gè) Stream<T> sorted(Comparator<? super T>
            
    // comparator);帶Comparator接口的參數(shù)
            stringList.stream().sorted().filter((s) -> s.startsWith("a")).forEach(System.out::println);

            // 輸出原始集合元素,sorted只是創(chuàng)建排序視圖,不影響原來集合順序
            stringList.stream().forEach(System.out::println);
        }

        /**
         * map是一個(gè)對(duì)于流對(duì)象的中間操作,通過給定的方法,它能夠把流對(duì)象中的每一個(gè)元素對(duì)應(yīng)到另外一個(gè)對(duì)象上。
         * 下面的例子就演示了如何把每個(gè)string都轉(zhuǎn)換成大寫的string.
         * 不但如此,你還可以把每一種對(duì)象映射成為其他類型。對(duì)于帶泛型結(jié)果的流對(duì)象,具體的類型還要由傳遞給map的泛型方法來決定。
         
    */
        public void useStreamMap() {
            // <R> Stream<R> map(Function<? super T, ? extends R> mapper);
            
    // map方法參數(shù)為Function函數(shù)式接口(R_String,T_String).

            
    // 解釋:將集合元素轉(zhuǎn)為大寫(每個(gè)元素映射到大寫)->降序排序->迭代輸出
            
    // 不影響原來集合
            stringList.stream().map(String::toUpperCase).sorted((a, b) -> b.compareTo(a)).forEach(System.out::println);
        }

        /**
         * 匹配操作有多種不同的類型,都是用來判斷某一種規(guī)則是否與流對(duì)象相互吻合的。所有的匹配操作都是終結(jié)操作,只返回一個(gè)boolean類型的結(jié)果
         
    */
        public void useStreamMatch() {
            // boolean anyMatch(Predicate<? super T> predicate);參數(shù)為Predicate函數(shù)式接口
            
    // 解釋:集合中是否有任一元素匹配以'a'開頭
            boolean anyStartsWithA = stringList.stream().anyMatch((s) -> s.startsWith("a"));
            System.out.println(anyStartsWithA);

            // boolean allMatch(Predicate<? super T> predicate);
            
    // 解釋:集合中是否所有元素匹配以'a'開頭
            boolean allStartsWithA = stringList.stream().allMatch((s) -> s.startsWith("a"));
            System.out.println(allStartsWithA);

            // boolean noneMatch(Predicate<? super T> predicate);
            
    // 解釋:集合中是否沒有元素匹配以'd'開頭
            boolean nonStartsWithD = stringList.stream().noneMatch((s) -> s.startsWith("d"));
            System.out.println(nonStartsWithD);
        }

        /**
         * Count是一個(gè)終結(jié)操作,它的作用是返回一個(gè)數(shù)值,用來標(biāo)識(shí)當(dāng)前流對(duì)象中包含的元素?cái)?shù)量
         
    */
        public void useStreamCount() {
            // long count();
            
    // 解釋:返回集合中以'a'開頭元素的數(shù)目
            long startsWithACount = stringList.stream().filter((s) -> s.startsWith("a")).count();
            System.out.println(startsWithACount);

            System.out.println(stringList.stream().count());
        }

        /**
         * 該操作是一個(gè)終結(jié)操作,它能夠通過某一個(gè)方法,對(duì)元素進(jìn)行削減操作。該操作的結(jié)果會(huì)放在一個(gè)Optional變量里返回。
         
    */
        public void useStreamReduce() {
            // Optional<T> reduce(BinaryOperator<T> accumulator);
            
    // @FunctionalInterface public interface BinaryOperator<T> extends
            
    // BiFunction<T,T,T> {

            
    // @FunctionalInterface public interface BiFunction<T, U, R> { R apply(T
            
    // t, U u);
            Optional<String> reduced = stringList.stream().sorted().reduce((s1, s2) -> s1 + "#" + s2);

            // 解釋:集合元素排序后->reduce(削減 )->將元素以#連接->生成Optional對(duì)象(其get方法返回#拼接后的值)
            reduced.ifPresent(System.out::println);
            System.out.println(reduced.get());
        }

        /**
         * 使用并行流
         * <p>
         * 流操作可以是順序的,也可以是并行的。順序操作通過單線程執(zhí)行,而并行操作則通過多線程執(zhí)行. 可使用并行流進(jìn)行操作來提高運(yùn)行效率
         
    */
        public void useParallelStreams() {
            // 初始化一個(gè)字符串集合
            int max = 1000000;
            List<String> values = new ArrayList<>();

            for (int i = 0; i < max; i++) {
                UUID uuid = UUID.randomUUID();
                values.add(uuid.toString());
            }

            // 使用順序流排序

            long sequenceT0 = System.nanoTime();
            values.stream().sorted();
            long sequenceT1 = System.nanoTime();

            // 輸出:sequential sort took: 51921 ms.
            System.out.format("sequential sort took: %d ms.", sequenceT1 - sequenceT0).println();

            // 使用并行流排序
            long parallelT0 = System.nanoTime();
            // default Stream<E> parallelStream() {
            
    // parallelStream為Collection接口的一個(gè)默認(rèn)方法
            values.parallelStream().sorted();
            long parallelT1 = System.nanoTime();

            // 輸出:parallel sort took: 21432 ms.
            System.out.format("parallel sort took: %d ms.", parallelT1 - parallelT0).println();

            // 從輸出可以看出:并行排序快了一倍多
        }

        public static void main(String[] args) {
            StreamUtilExample example = new StreamUtilExample();

            example.useStreamFilter();
            example.useStreamMap();
            example.useStreamMatch();
            example.useStreamCount();
            example.useStreamReduce();
            example.useParallelStreams();
        }
    }


        2.Map接口中新的默認(rèn)方法示例

    package com.mavsplus.java8.turtorial.streams;

    import java.util.HashMap;
    import java.util.Map;

    /**
     * map是不支持流操作的。而更新后的map現(xiàn)在則支持多種實(shí)用的新方法,來完成常規(guī)的任務(wù)
     * 
     * @author landon
     * @since 1.8.0_25
     
    */
    public class MapUtilExample {

        private Map<Integer, String> map = new HashMap<>();

        public MapUtilExample() {
            initPut();
        }

        /**
         * 使用更新后的map進(jìn)行putIfAbsent
         
    */
        private void initPut() {
            // putIfAbsent為Map接口中新增的一個(gè)默認(rèn)方法
            /**
             * <code>
                      default V putIfAbsent(K key, V value) {
                        V v = get(key);
                        if (v == null) {
                            v = put(key, value);
                        }

                        return v;
                      }
                      </code>
             
    */
            // 如果map中有對(duì)應(yīng)K映射的V且不為null則直接返回;否則執(zhí)行put
            for (int i = 0; i < 10; i++) {
                map.putIfAbsent(i, "value" + i);
            }

            // 放入了一個(gè)null元素
            map.putIfAbsent(10null);
            // 替換null
            map.putIfAbsent(10"value10");
            // 因?yàn)镵-10有映射且不為null則忽略V-value11
            map.putIfAbsent(10"value11");
        }

        /**
         * 使用更新后的map進(jìn)行for-each
         
    */
        public void forEach() {
            // default void forEach(BiConsumer<? super K, ? super V> action)
            
    // Map接口中新增的默認(rèn)方法

            
    // @FunctionalInterface public interface BiConsumer<T, U> {void accept(T
            
    // t, U u);
            map.forEach((id, val) -> System.out.println(val));
        }

        /**
         * 使用更新后的map進(jìn)行compute——->重映射
         
    */
        public void compute() {
            // default V computeIfPresent(K key,BiFunction<? super K, ? super V, ?
            
    // extends V> remappingFunction)

            
    // Map接口中新增的默認(rèn)方法

            
    // @FunctionalInterface public interface BiFunction<T, U, R> {R apply(T
            
    // t, U u);
            
    // --> V apply(K k,V v)

            
    // ifPresent會(huì)判斷key對(duì)應(yīng)的v是否是null,不會(huì)null才會(huì)compute->否則直接返回null

            
    // 解釋:將K-3映射的value->compute->"value3" + 3 = value33
            map.computeIfPresent(3, (key, val) -> val + key);
            System.out.println(map.get(3));

            // 解釋:這里將K-3映射的value進(jìn)行重映射->null
            
    // 該方法源碼實(shí)現(xiàn)會(huì)判斷如果newValue為null則會(huì)執(zhí)行remove(key)方法,將移除key
            map.computeIfPresent(9, (key, val) -> null);
            // 從上面的解釋中得到,輸出為false,因?yàn)橐呀?jīng)被移除了
            System.out.println(map.containsKey(9));

            // default V computeIfAbsent(K key,Function<? super K, ? extends V>
            
    // mappingFunction)
            
    // 解釋:代碼實(shí)現(xiàn)上看,如果K-15映射的值為null,即不存在或者為null,則執(zhí)行映射->所以本例來看(沒有15的key),該方法相當(dāng)于插入一個(gè)新值
            map.computeIfAbsent(15, (key) -> "val" + key);
            System.out.println(map.containsKey(15));

            // 因?yàn)镵-4映射的值存在,所以直接返回,即不會(huì)重映射,所以輸出依然會(huì)是value4
            map.computeIfAbsent(4, key -> "bam");
            System.out.println(map.get(4));
        }

        /**
         * 使用更新后的map進(jìn)行remove
         
    */
        public void remove() {
            // default boolean remove(Object key, Object value) {
            
    // Map接口中新增的默認(rèn)方法

            
    // 其源碼實(shí)現(xiàn)是
            
    // 1.當(dāng)前key對(duì)應(yīng)的值和傳入的參數(shù)不一致時(shí)則直接返回,移除失敗(用的是Objects.equals方法)
            
    // 2.當(dāng)前key對(duì)應(yīng)的值為null且!containsKey(key),移除失敗(即當(dāng)前map中根本不存在這個(gè)key_【因?yàn)橛幸环N情況是有這個(gè)key但是key映射的值為null】)
            
    // ->否則執(zhí)行移除

            /**
             * <code>
             *  default boolean remove(Object key, Object value) {
                    Object curValue = get(key);
                    if (!Objects.equals(curValue, value) ||
                        (curValue == null && !containsKey(key))) {
                        return false;
                    }
                    remove(key);
                    return true;
                }
             * </code>
             
    */
            map.remove(3"value4");
            System.out.println(map.get(3));

            // key和v匹配時(shí)則移除成功
            map.remove(3"value33");
            System.out.println(map.get(3));
        }

        /**
         * getOrDefault是一個(gè)有用的方法
         
    */
        public void getOrDefault() {
            // default V getOrDefault(Object key, V defaultValue) {
            
    // Map接口中新增的默認(rèn)方法

            /**
             * <code>
             * default V getOrDefault(Object key, V defaultValue) {
                V v;
                return (((v = get(key)) != null) || containsKey(key))
                    ? v
                    : defaultValue;
                }
             * </code>
             
    */

            // 源碼實(shí)現(xiàn):
            
    // 1.如果對(duì)應(yīng)的key有value且不為null,則直接返回value;如果為null且包含該key,則返回null(總之即必須要有該key)
            
    // 2.如果沒有該key,則用默認(rèn)值
            String retV = map.getOrDefault("20""not found");
            System.out.println(retV);

            // 加入一個(gè)null
            map.putIfAbsent(30null);
            // 輸出null
            System.out.println(map.get(30));
            // 輸出null
            System.out.println(map.getOrDefault(30"value30"));
        }

        /**
         * 合并
         
    */
        public void merge() {
            // default V merge(K key, V value,BiFunction<? super V, ? super V, ?
            
    // extends V> remappingFunction)

            
    // @FunctionalInterface public interface BiFunction<T, U, R> { R apply(T
            
    // t, U u);

            
    // merge為Map接口新增的默認(rèn)方法

            /**
             * <code>
             default V merge(K key, V value,
                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
                    Objects.requireNonNull(remappingFunction);
                    Objects.requireNonNull(value);
                    V oldValue = get(key);
                    V newValue = (oldValue == null) ? value :
                               remappingFunction.apply(oldValue, value);
                    if(newValue == null) {
                        remove(key);
                    } else {
                        put(key, newValue);
                    }
                return newValue;
             }
             * </code>
             
    */

            // 其源碼實(shí)現(xiàn):
            
    // 1.分別檢查參數(shù)remappingFunction和value是否為null(調(diào)用Objects.requireNonNull).->為null則拋出空指針
            
    // 2.判斷oldValue是否為null,如果為null則將傳入的newValue賦值;如果oldValue不為null則執(zhí)行merge函數(shù)
            
    // --->apply(oldValue, value)
            
    // 3.判斷newValue->如果為null則執(zhí)行移除;否則執(zhí)行插入

            
    // k-9的值在執(zhí)行compute方法的時(shí)候已經(jīng)被移除了->所以oldValue為null->所以newValue為傳入的參數(shù)value9->執(zhí)行插入
            
    // 所以這里輸出為value9
            String newValue1 = map.merge(9"value9", (value, newValue) -> value.concat(newValue));
            System.out.println(newValue1);
            System.out.println(map.get(9));

            // k-9的值現(xiàn)在已經(jīng)為value9了,所以執(zhí)行merge函數(shù)->"value9".concat("concat")->newValue為"value9concat"
            
    // 執(zhí)行插入,所以這里輸出為value9concat
            String newValue2 = map.merge(9"concat", (value, newValue) -> value.concat(newValue));
            System.out.println(newValue2);
            System.out.println(map.get(9));

            // k-8值存在為value8->執(zhí)行merge函數(shù)->直接返回"NewMerge8"->newValue為"NewMerge8"
            
    // 執(zhí)行put->所以這里輸出"NewMerge8"
            map.merge(8"merge", (value, newValue) -> "NewMerge8");
            System.out.println(map.get(8));
        }

        public static void main(String[] args) {
            MapUtilExample example = new MapUtilExample();

            example.forEach();
            example.compute();
            example.remove();
            example.getOrDefault();
            example.merge();
        }
    }


    posted on 2014-11-18 20:31 landon 閱讀(24530) 評(píng)論(1)  編輯  收藏 所屬分類: Program

    FeedBack:
    # re: Java8之Stream/Map[未登錄]
    2016-01-19 02:13 | jay
    總結(jié)的很詳細(xì)!  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 亚洲制服在线观看| 久久久久亚洲爆乳少妇无 | 亚洲精品视频免费| 在线永久免费观看黄网站| 亚洲精品视频在线播放| 91人人区免费区人人| 久久丫精品国产亚洲av不卡| 国产激情免费视频在线观看| 亚洲成AV人片在线观看ww| 色www永久免费网站| 久久综合日韩亚洲精品色| 亚洲一区二区在线免费观看| 久久亚洲精精品中文字幕| 99ee6热久久免费精品6| 亚洲成在人线电影天堂色| 国内免费高清在线观看| 亚洲精品无播放器在线播放| 免费观看午夜在线欧差毛片 | 女同免费毛片在线播放| 亚洲第一精品在线视频| 在线a免费观看最新网站| 亚洲成人黄色在线| 成年女人毛片免费视频| 校园亚洲春色另类小说合集| 亚洲乱码中文字幕综合234| a级毛片免费观看视频| 亚洲综合自拍成人| 成人免费午间影院在线观看| 免费一级毛片在线播放视频免费观看永久| 亚洲国产精品无码久久久蜜芽| 国产在线观看免费视频软件| 亚洲精品成人久久久| 久久国产精品国产自线拍免费| 亚洲精品国产福利片| 日韩免费视频播播| 久久精品免费观看| 亚洲欧美一区二区三区日产| 国产精品亚洲高清一区二区 | 国产免费播放一区二区| 亚洲精品电影天堂网| 四虎永久免费影院在线|