2016-08-11 12 views
2

私は、文字列値にマップする特定のキーを持つマップのリストを持っています。 List<Map<String,String>> aMapList;Javaマップのラムダ例外

目的よう

何か:マップのリスト経由でストリーミングし、すべてのマップで、単一のキーの値を収集。私はこれをやっている方法

- >

key = "somekey"; 
aMapList.stream().map(a -> a.get(key)).collect(Collectors.averagingInt()); 

問題: 私は例外によるそのようなキーが存在しない場合 a.get(キー)を取得!これを平均化するとnullが返されるためです。ラムダがそのような地図を無視して移動するかどうかを確認する方法

a -> a.contains(key)にフィルタを追加してから、処理を進めることができます。 編集:フィルタを追加したり、複数の条件を1つのフィルタに単純にチェックしたりすることもできます。 考えられる解決策:

aMapList.stream().filter(a -> a.contains(key)). 
     map(a -> a.get(key)).collect(Collectors.averagingInt()); 

これをきれいに行うことができますか? 操作を停止する代わりに、単に操作をスキップしますか? 例外やヌルをスキップするための一般的な方法がいくつかあります。 たとえば、私たちはラムダを広げてtry-catchブロックを置くことができますが、何かを返す必要があります。もし私が "continue"と同等のことをしたいのであれば、どうしたらいいですか?

例:上記はまだだけではなく、スキップのは、nullを返します>

(a -> {try{return a.get(key)} 
catch(Exception e){return null} }). 

-

(a -> {return a.get(key) }). 

はに拡張することができます。

私は2つのオプションを与えるための最良の答えを選択していますが、私はそれらのどれもきれいではありません。フィルタを連鎖させることがこれに対する解決策であると思われる。

+1

なぜ例外が発生しますか? nullにならないといけませんか? –

+0

私は1つの解決策を知っています。私はこれをもっと短時間でやり遂げることができるかどうか尋ねているだけです。フィルタが多すぎると醜く見えて混乱させます。 – Pranay

+0

@ cricket_007、将来の操作で例外がスローされるためです。私はnullを取得しますが、それは後で中断して例外をスローします。 – Pranay

答えて

2


あなたが提案するソリューションは、null値を許可マップのための潜在的なバグがあります。たとえば、次のようにMap documentationに基づいて

Map<String, String> aMap = new HashMap<>(); 
aMap.put("somekey", null); 

aMapList.add(aMap); 

aMapList.straem() 
    .filter(a -> a.contains("somekey")) // true returned for contains 
    .map(a -> a.get("somekey")) // null returned for get 
    .collect(Collectors.toList()); 
+0

null値をフィルターに入れることもできます。申し訳ありません。つまり、私はフィルタを連鎖させることで任意の数のものをフィルタリングすることができるので、nullもフィルタリングできます。私は "try {}、catch {ignore}"のようなやり方があるかどうか疑問に思っていました。そのようなケースは無視され、リストに移動します。 – Pranay

0

私がいたとまで来ることができ、最も単純な:

aMapList.stream() 
     .filter(map -> map.containsKey(key)) 
     .map(map -> map.get(key)) 
     .collect(Collectors.toList()); 

この方法でラムダをフォーマットすることで、そのコードプロセスの異なるステップを参照する方が簡単です。

+0

私はこれを可能な解決策として既に提案しました。私が尋ねようとしていることは、何か例外があってもラムダが作業を続けるための方法があるかどうかです。 – Pranay

+0

ラムダを読みやすく理解しやすいフォーマットを提案しています。私はこのラムダ(あなたが言っているように、あなたと基本的に同じです)は最も簡単な解決策だと思います。 – Jason

0

私は、これは正確にきれいなアプローチではありません数えるが、あなたができる:その後のコードが可能、空の要素を期待する知っているだろう

List<Optional<String>> values = aMapList.stream() 
      .map(a -> Optional.ofNullable(a.get(key))) 
      .collect(Collectors.toList()); 

:どのようにOptionalで結果をラップについて

aMapList.stream().map(a -> a.containsKey(key) ? a.get(key) : null).collect(Collectors.toList()); 
+1

'a.get(key)'がnullを返すので、それが含まれているかどうかをチェックすると無意味なように見えます。 –

+0

クリケットが言ったこと以外に、私は別のフィルタを追加するでしょう:) – Pranay

2

、そしてあなたの質問の下のあなたのコメントに、あなたが実際にa.get(key)から例外を取得していません。むしろ、その式はヌル値を生成し、これらのヌル値を実行すると問題が発生します。だから、単純に正常に動作する必要がありますすぐにこれらのNULL値をフィルタリング:

aMapList.stream() 
    .map(a -> a.get(key)) 
    .filter(v -> v != null) 
    .collect(Collectors.toList()); 

これは、きれいに簡単で、あなたの問題の回避策よりもパフォーマンスが向上します。

ヌル値を扱うときには通常Optional<>タイプが好ましいと言わざるを得ないが、マップリストにキーが存在しない要素を無視すると具体的に言っているので、このフィルタリングの方が効果的です。

+0

'v!= null'にする必要があります。 –

+1

@LukeLee 'v!= null'は、マップに' null'値を持つキーがあるときにも潜在的なバグがあります。 –

+0

現在、一般的なケースでは正しい結果が得られないと心配しています。 –