2016-08-25 8 views
1

私はいくつかのケースで不変のマップエレガントな方法Java 8のMapに値以外を追加するには?

public Map<String,String> getMap(){ 
     return ImmutableMap.<String,String>builder() 
       .put("FOO",getFooType()) 
       .put("BAR", getBarType()) 
       .build(); 
    } 

を使用しています、getFooType()またはgetBarType()はnullを返します。そのため、例外はcom.google.common.collect.ImmutableMapからスローされます。私は、nullでない空文字列だけでマップを設定する上品な方法があるのだろうかと思います。

グーバのライブラリに限定されているわけではありません。

私はマップに追加する多くのキー、チェックがあれば、コードがきれいではありません作るのこの種を持っているので、私は、次の

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

String fooType = getFooType(); 
String barType = getBarType(); 

if (fooType!=null && fooType.length()>0){ 
    map.put("FOO", fooType); 
} 

if (barType!=null && barType.length()>0){ 
    map.put("BAR", barType); 
} 

と離れて行うことができます。私はそれを行うためのエレガントな方法があるのだろうかと思っています。

私は自分のプロジェクトにJava 8を使用しています。これは与える -

public Map<String,Optional<String>> getMap(){ 
    return ImmutableMap.<String,Optional<String>>builder() 
    .put("FOO",Optional.<String>ofNullable(getFooType())) 
    .put("BAR", Optional.<String>ofNullable(getBarType())) 
    .build(); 
} 

マップは任意のオブジェクトは、あなたの文字列をラップし、あなたがマップから値を取得するときに、map.get(key).orElse(DEF_VALUE);を使用し保存します。この方法:あなたがマップの値としてOptionalを使用することができます

+0

そして、これらの '' getFooType'とgetBarType'は静的メソッドですか? –

+0

地図に入るアイテムの出所は? – bradimus

+0

これらは静的メソッドではありません。マップするアイテムはメソッド呼び出しから来ています。メソッドはマップを返す必要があります –

答えて

4

NULL値を持つもののDEF_VALUEを指定します。よく、それらが繰り返され、ため

もっと見るhere

+0

良い。 'getMap()'が 'Map >'でいくつかの後処理をして 'Map 'を返すことができるのだろうか? –

+1

'MapUtils'(guavaやapacheCommonsの場合は覚えていません)を見てください。フィルターを使用して値が空のオプションであるものを除外し、convertを使用して残りのオプションの値をgrtすることができます。 (しかし、あなたが私に尋ねるなら、それが可能なら、それをeithのオプションとして残してください) –

2

繰り返し

if (fooType!=null) { 
    map.put("FOO", fooType); 
} 

は冗長に見えます。条件付き加算演算をメソッドに追加して再利用するだけであれば、コードは最初の非条件付きコードと同じくらいコンパクトに見えます。これは、必要なマッピングごとに1つのメソッド呼び出しで構成されるためです。

あなたは簡単にグアバのアプローチでこれを組み合わせることができます注:

class MyBuilder<K,V> extends ImmutableMap.Builder<K,V> { 
    public MyBuilder<K, V> putIfValueNotNull(K key, V value) { 
     if(value!=null) super.put(key, value); 
     return this; 
    } 
} 

...

public Map<String,String> getMap(){ 
    return new MyBuilder<String,String>() 
      .putIfValueNotNull("FOO",getFooType()) 
      .putIfValueNotNull("BAR", getBarType()) 
      .build(); 
} 

あなたがいることを好む場合は、builder()種類のファクトリメソッドへMyBuilder作成をラップすることができますコーディングスタイル。

2

ピュアJavaの8ソリューション:

public Map<String, String> getMap() { 
    return Stream.of(
      new AbstractMap.SimpleEntry<>("FOO", getFooType()), 
      new AbstractMap.SimpleEntry<>("BAR", getBarType()) 
    ) 
      .filter(entry -> entry.getValue() != null) 
      .filter(entry -> !entry.getValue().isEmpty()) 
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 
} 
+0

これは素晴らしいです - ありがとう! – anon58192932

関連する問題