2017-06-16 11 views
3

私はJava 8のラムダやものに非常に新しいです...私は、JsonArrayをとり、そのJsonObjectsを調べ、特定のフィールドの値のリストを作成するラムダ関数を書いてみたいと思います。Java 8:JsonArrayで動作するようにラムダストリームを書き込む方法は?

たとえば、JsonArray:[{name: "John"}、{name: "David"}]を取得し、["John"、 "David"]のリストを返す関数。

私は、次のコードを書いた:

import org.json.simple.JSONArray; 
import org.json.simple.JSONObject; 

public class Main { 
    public static void main(String[] args) { 
     JSONArray jsonArray = new JSONArray(); 
     jsonArray.add(new JSONObject().put("name", "John")); 
     jsonArray.add(new JSONObject().put("name", "David")); 
     List list = (List) jsonArray.stream().map(json -> json.toString()).collect(Collectors.toList()); 
     System.out.println(list); 
    } 
} 

はしかし、私はエラーを取得する:

Exception in thread "main" java.lang.NullPointerException

は、あなたはそれを解決する方法を知っていますか?

+2

'(入れ)は'あなたのケースでは 'null'なのでを意味し、その名によって*以前の*値を返します。 'put()'は連鎖法ではありません(https://en.wikipedia.org/wiki/Method_chaining)。 – Andreas

答えて

4

JSONArrayは、java.util.ArrayListのサブクラスであり、JSONObjectは、java.util.HashMapのサブクラスです。

したがって、new JSONObject().put("name", "John")は、JSONObjectインスタンスではなく、キー(null)に関連付けられた以前の値を返します。結果としてnullJSONArrayに追加されます。

これは、他の一方で、動作します:

JSONArray jsonArray = new JSONArray(); 
    JSONObject j1 = new JSONObject(); 
    j1.put ("name", "John"); 
    JSONObject j2 = new JSONObject(); 
    j2.put ("name", "David"); 
    jsonArray.add(j1); 
    jsonArray.add(j2); 
    Stream<String> ss = jsonArray.stream().map (json->json.toString()); 
    List<String> list = ss.collect (Collectors.toList()); 
    System.out.println(list); 

を、私はそうでない場合、コンパイラは.collect (Collectors.toList())Listを返すことを認識していないため、2つのステップにストリームパイプラインを分割しなければならなかったいくつかの理由。

出力は次のとおりです。

[{"name":"John"}, {"name":"David"}] 
+2

Raw 'ArrayList'と' HashMap'は 'stream()'パイプラインがコンパイルされなかった理由です。 –

+0

私は 'JSONArray'が生の' ArrayList'を拡張していることを前提としていましたが、 '.map(json-> json.toString())'の後にコンパイラは結果が 'Stream 'と呼ばれ、元の生の' Stream'の要素のタイプにかかわらずです。 – Eran

+2

私はそれが_could_だと思いますが、 'map'は生の' Stream'の呼び出しから直ちに消去されます。 –