成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Map 只會 put、get?快來學這幾個“新”方法

開發 前端
目前JDK的最新LTS版本已經更新到21了,這幾個在JDK8引入的Map”新“方法其實也是”老“方法了,還沒熟練使用也太out了,快來看看你都”學廢“了嗎?

引子

Map的數據操作,你是不是還只會put、get?

Map是我們日常編程中十分常用的數據接口,的在JDK8中,Map引入了幾個新方法,可以簡化我們對Map中數據的操作。

目前JDK的最新LTS版本已經更新到21了,這幾個在JDK8引入的Map”新“方法其實也是”老“方法了,還沒熟練使用也太out了,快來看看你都”學廢“了嗎?

getOrDefault

這個方法名很直觀,見名知意:嘗試獲取key對應的值,如果未獲取到,就返回默認值。

看一個使用的例子,新寫法會比老寫法更加簡潔:

private static void testGetOrDefault() {
    Map<String, String> map = new HashMap<>(4);
    map.put('123', '123');
    String key = 'key';
    String defaultValue = 'defaultValue';

    // 老寫法
    String oldValue = defaultValue;
    if (map.containsKey(key)) {
        oldValue = map.get(key);
    }
    System.out.println('oldValue = ' + oldValue);

    // 新寫法
    String newValue = map.getOrDefault(key, defaultValue);
    System.out.println('newValue = ' + newValue);
}

foreach

看方法名也可以知道,這個方法是遍歷map的數據使用的。

如果沒有foreach,我們遍歷map的時候一般是使用增強for循環,有了這個方法后,可以更加方便使用entry中的key和val:

private static void testForeach() {
    Map<String, String> map = new HashMap<>(4);
    map.put('123', '123');

    // 老寫法
    for (Map.Entry<String, String> entry : map.entrySet()) {
        System.out.printf('老寫法 key = %s, value = %s%n', entry.getKey(), entry.getValue());
    }

    // 新寫法
    map.forEach((key, value) -> System.out.printf('新寫法 key = %s, value = %s%n', key, value));
}

merge

從名字可以想到,是合并entry使用的,但是具體是怎么合并呢?

看一下日常最常用的Map實現類HashMap對merge方法的實現

@Override
public V merge(K key, V value,
               BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    if (value == null || remappingFunction == null)
        throw new NullPointerException();
    int hash = hash(key);
    Node<K,V>[] tab; Node<K,V> first; int n, i;
    int binCount = 0;
    TreeNode<K,V> t = null;
    Node<K,V> old = null;
    if (size > threshold || (tab = table) == null ||
        (n = tab.length) == 0)
        n = (tab = resize()).length;
    if ((first = tab[i = (n - 1) & hash]) != null) {
        if (first instanceof TreeNode)
            old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key);
        else {
            Node<K,V> e = first; K k;
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k)))) {
                    old = e;
                    break;
                }
                ++binCount;
            } while ((e = e.next) != null);
        }
    }
    if (old != null) {
        V v;
        if (old.value != null) {
            int mc = modCount;
            v = remappingFunction.apply(old.value, value);
            if (mc != modCount) {
                throw new ConcurrentModificationException();
            }
        } else {
            v = value;
        }
        if (v != null) {
            old.value = v;
            afterNodeAccess(old);
        }
        else
            removeNode(hash, key, null, false, true);
        return v;
    } else {
        if (t != null)
            t.putTreeVal(this, tab, hash, key, value);
        else {
            tab[i] = newNode(hash, key, value, first);
            if (binCount >= TREEIFY_THRESHOLD - 1)
                treeifyBin(tab, hash);
        }
        ++modCount;
        ++size;
        afterNodeInsertion(true);
        return value;
    }
}

代碼比較長,但是實現的效果比較容易描述:這個方法接收3個參數:key、value、function。

  • 如果key存在,將value按照function做1次計算后,更新到Map中
  • 如果key不存在,將key-value放入Map中

這個方法在某些場景中挺好用的,代碼簡潔易懂,例如:我們有1個List,要統計List中每個元素出現的次數。我們要實現的邏輯是,遍歷List中的每個元素,如果這個元素在Map中存在,Map中的值+1;如果不存在,則放入Map中,次數(值)為1。

private static void testMerge() {
    Map<String, Integer> cntMap = new HashMap<>(8);
    List<String> list = Arrays.asList('apple', 'orange', 'banana', 'orange');

    // 老寫法
    for (String item : list) {
        if (cntMap.containsKey(item)) {
            cntMap.put(item, cntMap.get(item) + 1);
        } else {
            cntMap.put(item, 1);
        }
    }

    // 新寫法
    for (String item : list) {
        cntMap.merge(item, 1, Integer::sum);
    }
}

可以看到我們使用merge方法的話,只用1行就簡潔實現了這個邏輯。

putIfAbsent

也是一個見名知意的方法:不存在key或者值為null時,才將鍵值對放入Map。跟put方法相比,這個方法不會直接覆蓋已有的值,在不允許覆蓋舊值的場景使用起來會比較簡潔。

private static void testPutIfAbsent() {
    Map<String, Integer> scoreMap = new HashMap<>(4);
    scoreMap.put('Jim', 88);
    scoreMap.put('Lily', 90);

    // 老寫法
    if (!scoreMap.containsKey('Lily')) {
        scoreMap.put('Lily', 98);
    }

    // 新寫法
    scoreMap.putIfAbsent('Lily', 98);
}

computer

computer方法需要傳入2個參數:key、function。主要有3步操作

  • 獲取到key對應的oldValue,可能為null
  • 經過function計算獲取newValue
  • put(key, newValue)

還是以剛剛統計單次次數需求為例,看一下computer的寫法:

private static void testComputer() {
    Map<String, Integer> cntMap = new HashMap<>(8);
    List<String> list = Arrays.asList('apple', 'orange', 'banana', 'orange');

    // 老寫法
    for (String item : list) {
        if (cntMap.containsKey(item)) {
            cntMap.put(item, cntMap.get(item) + 1);
        } else {
            cntMap.put(item, 1);
        }
    }

    // 新寫法
    for (String item : list) {
        cntMap.compute(item, (k, v) -> {
            if (v == null) {
                v = 1;
            } else {
                v += 1;
            }
            return v;
        });
    }
}

computeIfAbsent

看名字就知道是compute方法衍生出來的方法,這個方法只在key不存在的時候,執行computer計算,如果說key對應的value存在,就直接返回這個value。

例如,我們需要計算斐波那鍥數列的時候,可以使用這個方法來簡化代碼:

private static void testComputerIfAbsent() {
    Map<Integer, Integer> fabMap = new ConcurrentHashMap<>(16);
    fabMap.put(0, 1);
    fabMap.put(1, 1);
    System.out.println(fab(5, fabMap));
}

private static Integer fab(Integer index, Map<Integer, Integer> fabMap) {
    return fabMap.computeIfAbsent(index, i -> fab(i - 2, fabMap) + fab(i - 1, fabMap));
}

computeIfPresent

這個是computeIfAbsent的姊妹方法,區別在于,這個方法是只有key存在的時候,才去執行computer計算和值的更新。

replace

這個方法的效果是:

  • 如果key存在,則更新值
  • 如果key不存在,什么也不做
責任編輯:武曉燕 來源: JAVA日知錄
相關推薦

2020-05-20 16:54:47

數據分頁顯示函數

2021-09-15 16:05:41

map.putJavaMap

2022-05-27 08:44:09

springStarter配置

2020-09-18 06:48:21

Python編程語言

2023-10-07 08:59:02

2020-07-03 18:14:20

JavaScript開發技術

2021-06-11 13:59:22

CSS原子類

2021-10-27 10:07:59

GitHub代碼開發者

2020-02-03 09:29:32

JavaScript代碼斷點

2019-02-28 20:20:43

Python技巧編程語言

2023-11-30 08:19:52

偽類CSS

2024-07-01 08:31:14

Spring工具類代碼

2022-05-20 15:27:41

React工具Vue

2020-03-06 10:54:51

Go語言XML算法

2018-06-19 16:25:40

編程語言Python爬蟲

2022-12-22 08:57:29

Redis數據存儲

2022-02-20 20:12:21

TypeScript

2022-02-21 16:16:24

災難恢復解決方案備份

2022-04-12 08:43:21

Python內置模塊

2018-04-18 06:56:26

iPhone手機電量
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄网站在线播放 | 99reav| 伊人色综合久久天天五月婷 | 国产乱码精品一区二区三区五月婷 | 久久久久久久香蕉 | 午夜99| 国产精品a久久久久 | 欧美精品乱码99久久影院 | 日本免费网 | 国产一区二区三区久久久久久久久 | 久久久www | 国产在线视频99 | 免费啪啪 | 久久久久久久久久久久久久国产 | 日韩欧美国产精品一区 | 成人福利网站 | 免费a国产 | 久久精品这里精品 | 人人玩人人干 | aaaaaaa片毛片免费观看 | 久久综合99 | 免费观看一级毛片视频 | 午夜免费| 国产精品无码专区在线观看 | 久久久九九九九 | av大片 | 秋霞影院一区二区 | xnxx 日本免费 | 国产精品激情在线 | 欧美一区二区三区在线观看视频 | 一级毛片视频 | 九九热免费观看 | 精品九九在线 | 99国产精品久久久久 | 国产精品一区二区三区在线播放 | 国产精品久久久久久久久免费桃花 | 91人人在线 | 久久国产免费看 | 羞羞视频免费在线观看 | 欧美视频成人 | 欧美a在线 |