2017-10-09 19 views
1
のJava 8と9のマップに文字列値を連結するための最も便利な方法です

の中でキーで文字列値を連結しますこのコードは実際には:最も便利なイディオムは、私はこのプロジェクトで、現在このコードを持っているJavaの

と同じですか?

他にも優れた選択肢はありますか?

+0

それは私には思える、単に読み取ることによって、 2つ目のコード( 'merge'を使って)がかなり明らかに便利です。 – DodgyCodeException

答えて

2

のJavaDoc(私が強調)に述べたようにはい、両方の方法は、(約)と等価であるべきである。

指定されたキーが既に値と関連付けられていないか、ヌルに関連付けられている場合、関連付け与えられたのヌルではないの値です。それ以外の場合は、関連する値を指定された再マップ関数の結果に置き換えます。または結果がnullの場合は削除します。実際に

、1つのマイナーな違いがあります:マップがすでにxxxnullまたは任意の他の文字列である可能性が値"null and xxx"を取得していないと思い指定されたキーのnullが含まれている場合。代わりにvaluenullになるか、ちょうどvalueを追加すると、NullPointerExceptionが発生します。

あなたがMap.merge(...)のソースを見ればあなたがこの表示されます: ``ということ

V oldValue = containsKey(key) ? get(key) : null; 
V newValue = (oldValue == null) ? value : 
    remappingFunction.apply(oldValue, value); 
if(newValue == null) { 
    remove(key); 
} else { 
    put(key, newValue); 
} 

注:より密接これはのように書くことができ、あなたの第一の方法に似ていると

V oldValue = get(key); 
V newValue = (oldValue == null) ? value : 
    remappingFunction.apply(oldValue, value); 
if(newValue == null) { 
    remove(key); 
} else { 
    put(key, newValue); 
} 

をあなたが渡したラムダはinvalidMap.get(key) + " and " + newMessages + "and" + s2)に相当します。あなたは、ラムダとその機能を置き換えるのであれば、あなたはこのような何かを得るでしょう:

V oldValue = containsKey(key) ? get(key) : null; 
V newValue = (oldValue == null) ? value : 
    oldValue + " and " + value; //oldValue would be s and value would be s2 
if(newValue == null) { 
    remove(key); 
} else { 
    put(key, newValue); 
} 

あなたはマップがnullの値を持つキーが含まれているか、それを処理しないことを確認する必要があると思います言われていることあなたの必要に応じて。

+0

ええと、私はあなたの最後の文章を確認しようとしましたが、これは何の違いもないようです。それでもあなたの答えは高く評価されます。 –

0

また、5つの異なる方法でこの問題を処理するための5つのバリエーションを使用した簡単なテストを使用して、この質問の代替案を見つけようとしました。また、ユーザーがnullの使用について述べたことを検証しようとしました。ここで

は私のおもちゃの検証コードです:

public static void main(String[] args) throws ParseException, ClassNotFoundException, IllegalAccessException { 
    Map<String, ? super CharSequence> m1 = new HashMap<>(); 
    Map<String, ? super CharSequence> m2 = new HashMap<>(); 
    Map<String, ? super CharSequence> m3 = new HashMap<>(); 
    Map<String, ? super CharSequence> m4 = new HashMap<>(); 
    Map<String, StringBuilder> m5 = new HashMap<>(); 
    m1.put("k1", null); // validating Thomas answer to see, if this does change anything. 
    addToMaps("k1", "v1", m5, m1, m2, m3, m4); 
    addToMaps("k1", "v1_1",m5, m1, m2, m3, m4); 
    addToMaps("k1", "v1_3",m5, m1, m2, m3, m4); 
    addToMaps("k2", "v2", m5, m1, m2, m3, m4); 
    addToMaps("k3", "v3", m5, m1, m2, m3, m4); 
    addToMaps("k3", "v3_1",m5, m1, m2, m3, m4); 
    System.out.printf("m1: %s%n", m1); 
    System.out.printf("m2: %s%n", m2); 
    System.out.printf("m3: %s%n", m3); 
    System.out.printf("m4: %s%n", m4); 
    System.out.printf("m5: %s%n", m5); 
} 

private static void addToMaps(String key, String value, 
           Map<String, StringBuilder> builderMap, 
           Map<String, ? super CharSequence>... invalidMaps) { 
    builderMap.computeIfAbsent(key, (k) -> new StringBuilder()).append(" and ").append(value); 
    addToMap4(invalidMaps[3], key, value); 
    addToMap1(invalidMaps[0], key, value); 
    addToMap2(invalidMaps[1], key, value); 
    addToMap3(invalidMaps[2], key, value); 
} 

private static void addToMap1(Map<String, ? super CharSequence> invalidMap, String key, String value) { 
    if (invalidMap.computeIfPresent(key, (k, v) -> v + " and " + value) == null) { 
     invalidMap.put(key, value); 
    } 
} 

private static void addToMap2(Map<String, ? super CharSequence> invalidMap, String key, String newMessage) { 
    if (invalidMap.containsKey(key)) { 
     invalidMap.put(key, invalidMap.get(key) + " and " + newMessage); 
    } else { 
     invalidMap.put(key, newMessage); 
    } 
} 

private static void addToMap4(Map<String, ? super CharSequence> invalidMap, String key, String newMessage) { 
    String value = (String) invalidMap.get(key); 
    if (value == null) { 
     invalidMap.put(key, newMessage); 
    } else { 
     invalidMap.put(key, value + " and " + newMessage); 
    } 
} 

private static void addToMap3(Map<String, ? super CharSequence> invalidMap, String key, String value) { 
    invalidMap.merge(key, value, (s, s2) -> s + " and " + s2); 
} 

は、これは別の連接方法で処理されている5つのマップに表示しますものです:

m1: {k1=v1 and v1_1 and v1_3, k2=v2, k3=v3 and v3_1} 
m2: {k1=v1 and v1_1 and v1_3, k2=v2, k3=v3 and v3_1} 
m3: {k1=v1 and v1_1 and v1_3, k2=v2, k3=v3 and v3_1} 
m4: {k1=v1 and v1_1 and v1_3, k2=v2, k3=v3 and v3_1} 
m5: {k1= and v1 and v1_1 and v1_3, k2= and v2, k3= and v3 and v3_1} 
関連する問題