TomX
TomX

Reputation: 69

type lost when using java8 stream api

code first:

    net.sf.json.JSONArray ja = new net.sf.json.JSONArray();
    for (int i = 0; i < 3; i++) {
        net.sf.json.JSONObject obj = new net.sf.json.JSONObject();
        obj.put("number", "k"+i);
        ja.add(obj);
    }
    System.out.println(ja.stream().map(s->((net.sf.json.JSONObject)s).getString("number")).peek(s->System.out.println(s.getClass())).collect(Collectors.joining(";")));

as you can see, I try to get a String of JSONObject and join them. And it works above like this:

    class java.lang.String
    class java.lang.String
    class java.lang.String
    k0;k1;k2

However ja.stream().map(s->((JSONObject)s).getString("number")) seems return not a Stream<String> but Stream<Object> which I couldn't append String intermidiate operation like .map(s->s.substring(3)). In other words, type lost.

So can anybody give any advice?

Upvotes: 1

Views: 436

Answers (1)

Harmlezz
Harmlezz

Reputation: 8068

Breaking down your stream statement does result in:

net.sf.json.JSONArray ja = new net.sf.json.JSONArray();
Stream stream1 = ja.stream();
Stream stream2 = stream1.map(s -> ((JSONObject) s).getString("number"));

As you can see, stream1 is not of a generic type. Hence any transformations will not produce a generic type out of a non generic type. Changing either variable ja or variable stream1 to a generic type will result in a Stream<String> for variable stream2:

net.sf.json.JSONArray ja = new net.sf.json.JSONArray();
Stream<Object> stream1 = ja.stream();
Stream<String> stream2 = stream1.map(s -> ((JSONObject) s).getString("number"));

Hence if you want to preserve type information you need a generic type which may carry it.

Upvotes: 3

Related Questions