1. 程式人生 > >java8新特性——函數語言程式設計(stream/map)

java8新特性——函數語言程式設計(stream/map)

複製程式碼
package com.mavsplus.java8.turtorial.streams;

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

/**
 * map是不支援流操作的。而更新後的map現在則支援多種實用的新方法,來完成常規的任務
 * 
 * @author landon
 * @since 1.8.0_25
 */
public class MapUtilExample {

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

    public MapUtilExample() {
        initPut();
    }

    
/** * 使用更新後的map進行putIfAbsent */ private void initPut() { // putIfAbsent為Map介面中新增的一個預設方法 /** * <code> default V putIfAbsent(K key, V value) { V v = get(key); if (v == null) { v = put(key, value); } return v; } </code>
*/ // 如果map中有對應K對映的V且不為null則直接返回;否則執行put for (int i = 0; i < 10; i++) { map.putIfAbsent(i, "value" + i); } // 放入了一個null元素 map.putIfAbsent(10, null); // 替換null map.putIfAbsent(10, "value10"); // 因為K-10有對映且不為null則忽略V-value11 map.putIfAbsent(10, "value11"); }
/** * 使用更新後的map進行for-each */ public void forEach() { // default void forEach(BiConsumer<? super K, ? super V> action) // Map介面中新增的預設方法 // @FunctionalInterface public interface BiConsumer<T, U> {void accept(T // t, U u); map.forEach((id, val) -> System.out.println(val)); } /** * 使用更新後的map進行compute——->重對映 */ public void compute() { // default V computeIfPresent(K key,BiFunction<? super K, ? super V, ? // extends V> remappingFunction) // Map介面中新增的預設方法 // @FunctionalInterface public interface BiFunction<T, U, R> {R apply(T // t, U u); // --> V apply(K k,V v) // ifPresent會判斷key對應的v是否是null,不會null才會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進行重對映->null // 該方法原始碼實現會判斷如果newValue為null則會執行remove(key)方法,將移除key map.computeIfPresent(9, (key, val) -> null); // 從上面的解釋中得到,輸出為false,因為已經被移除了 System.out.println(map.containsKey(9)); // default V computeIfAbsent(K key,Function<? super K, ? extends V> // mappingFunction) // 解釋:程式碼實現上看,如果K-15對映的值為null,即不存在或者為null,則執行對映->所以本例來看(沒有15的key),該方法相當於插入一個新值 map.computeIfAbsent(15, (key) -> "val" + key); System.out.println(map.containsKey(15)); // 因為K-4對映的值存在,所以直接返回,即不會重對映,所以輸出依然會是value4 map.computeIfAbsent(4, key -> "bam"); System.out.println(map.get(4)); } /** * 使用更新後的map進行remove */ public void remove() { // default boolean remove(Object key, Object value) { // Map介面中新增的預設方法 // 其原始碼實現是 // 1.當前key對應的值和傳入的引數不一致時則直接返回,移除失敗(用的是Objects.equals方法) // 2.當前key對應的值為null且!containsKey(key),移除失敗(即當前map中根本不存在這個key_【因為有一種情況是有這個key但是key對映的值為null】) // ->否則執行移除 /** * <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匹配時則移除成功 map.remove(3, "value33"); System.out.println(map.get(3)); } /** * getOrDefault是一個有用的方法 */ public void getOrDefault() { // default V getOrDefault(Object key, V defaultValue) { // Map介面中新增的預設方法 /** * <code> * default V getOrDefault(Object key, V defaultValue) { V v; return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue; } * </code> */ // 原始碼實現: // 1.如果對應的key有value且不為null,則直接返回value;如果為null且包含該key,則返回null(總之即必須要有該key) // 2.如果沒有該key,則用預設值 String retV = map.getOrDefault("20", "not found"); System.out.println(retV); // 加入一個null map.putIfAbsent(30, null); // 輸出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介面新增的預設方法 /** * <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> */ // 其原始碼實現: // 1.分別檢查引數remappingFunction和value是否為null(呼叫Objects.requireNonNull).->為null則丟擲空指標 // 2.判斷oldValue是否為null,如果為null則將傳入的newValue賦值;如果oldValue不為null則執行merge函式 // --->apply(oldValue, value) // 3.判斷newValue->如果為null則執行移除;否則執行插入 // k-9的值在執行compute方法的時候已經被移除了->所以oldValue為null->所以newValue為傳入的引數value9->執行插入 // 所以這裡輸出為value9 String newValue1 = map.merge(9, "value9", (value, newValue) -> value.concat(newValue)); System.out.println(newValue1); System.out.println(map.get(9)); // k-9的值現在已經為value9了,所以執行merge函式->"value9".concat("concat")->newValue為"value9concat" // 執行插入,所以這裡輸出為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->執行merge函式->直接返回"NewMerge8"->newValue為"NewMerge8" // 執行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(); } }