public static <K, V> V computeIfAbsent(ConcurrentMap<K, V> map, K key, Function<? super K, ? extends V> func) {
        Objects.requireNonNull(func);
        if (isJdk8) {
            V v = map.get(key);
            if (null == v) {
                // this bug fix methods maybe cause `func.apply` multiple calls.
                v = func.apply(key);
                if (null == v) {
                    return null;
                }
                final V res = map.putIfAbsent(key, v);
                if (null != res) {
                    // if pre value present, means other thread put value already, and putIfAbsent not effect
                    // return exist value
                    return res;
                }
            }
            return v;
        } else {
            return map.computeIfAbsent(key, func);
        }
    }
@Test
    public void computeIfAbsent() {
        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
        map.put("123", "1111");
        String value = ConcurrentHashMapUtils.computeIfAbsent(map, "123", k -> "234");
        assertEquals("1111", value);
        String value1 = ConcurrentHashMapUtils.computeIfAbsent(map, "1232", k -> "2342");
        assertEquals("2342", value1);
        String value2 = ConcurrentHashMapUtils.computeIfAbsent(map, "123", k -> "2342");
        assertEquals("1111", value2);
    }