问题在于:
public static <T> T execute(String query, Function<List<JsonNode>, T> function) {
String jsonString = HttpRequest.get("http://overpass-api.de/api/interpreter", true, "data", query).body();
List<JsonNode> list = toJsonNodeList(jsonString);
T res = function.apply(list);
return res;
}
此方法:
这是将每个JsonNode转换为geojson几何体并返回geojson结果集的函数示例:
public class GeojsonMapper implements Function<List<JsonNode>, GeojsonSingleListResultSet> {
@Override
public GeojsonSingleListResultSet apply(List<JsonNode> list) {
List<Element> elementList = list.parallelStream()
.map(jsonNode -> {
String id = jsonNode.get("id").asText();
JsonNode tags = jsonNode.get("tags");
switch (jsonNode.get("type").asText()) {
case "node":
return new Point(jsonNode.get("lat").asDouble(), jsonNode.get("lon").asDouble(), id, tags);
case "way":
ArrayList<Point> points = new ArrayList<>();
JsonNode nodeList = jsonNode.get("geometry");
for (int j = 0; j < nodeList.size(); j++) {
JsonNode wayNode = nodeList.get(j);
points.add(j, new Point(wayNode.get("lat").asDouble(), wayNode.get("lon").asDouble()));
}
if (Polygon.isPolygon(points, tags)) {
return new Polygon(points, id, tags);
} else {
return new LineString(points, id, tags);
}
default:
Iterator<JsonNode> iterator = jsonNode.get("members").getElements();
List<List<Point>> rings = new ArrayList<>();
List<Point> ring = null;
while (iterator.hasNext()) {
JsonNode member = iterator.next();
JsonNode geometry = member.get("geometry");
ring = new ArrayList<>();
for (int ringIndex = 0; ringIndex < geometry.size(); ringIndex++) {
JsonNode coordinates = geometry.get(ringIndex);
ring.add(new Point(coordinates.get("lat").asDouble(), coordinates.get("lon").asDouble()));
}
rings.add(ring);
}
return new Multipolygon(Polygon.buildPolygons(rings), id, tags);
}
})
.collect(toList());
return new GeojsonSingleListResultSet(elementList);
}
}
一切都运行良好,但与使用Stream的方法function.apply()相比,toJsonNodeList()方法非常慢。这是toJsonNodeList()的代码:
private static List<JsonNode> toJsonNodeList(String s){
ObjectMapper mapper = new ObjectMapper();
List<JsonNode> list = new ArrayList<>();
try{
JsonNode resultSet = mapper.readTree(s).get("elements");
Iterator<JsonNode> iterator = resultSet.getElements();
while (iterator.hasNext()) {
list.add(iterator.next());
}
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
有没有办法使用parallelStream解析json字符串,以便提取每个元素并将其转换为JsonNode? p>