java ·Jackson:获取所有子元素的数量[duplicate]

oalqel3c  于 2022-11-09  发布在  Java
关注(0)|答案(3)|浏览(122)

此问题在此处已有答案

Java Stream API - count items of a nested list(3个答案)
8个月前关门了。
我有下面的一段JSON代码:

{
    "films": [{
            "id": "12345",
            "title": "The Fellowship Of The Ring",
            "year": 2001,
            "cast": [{
                    "actor": "Billy Boyd",
                    "id": "770911234",
                    "character": "Peregrin Took"
                },
                {
                    "actor": "Ian McKellen",
                    "id": "162659743",
                    "character": "Gandalf"
                }
            ]
        },
        {
            "id": "67890",
            "title": "Spiderman",
            "year": 2021,
            "cast": [{
                "actor": "Tom Holland",
                "id": "162660329",
                "character": "Spiderman"
            }]
        }
    ]
}

我对使用Jackson还是个新手,现在想知道,用Java获取所有电影对象的所有演员的数量的最好方法是什么?是从movies对象解析它,还是创建一个单独的解析方法?
我已经创建了一个JsonFilm POJO,它包含一个film对象的字段和一个带有getter+setter的JsonFilms类:

public class JsonFilms {

    @JsonProperty("films")
    private List<JsonFilms > jsonFilmList = new ArrayList<>();

    public List<JsonFilm> getFilmsList() {
        return Collections.unmodifiableList(jsonFilmList );
    }

    public void setFilmsList(List<JsonFilm> jsonFilmList ) {
        this.jsonFilmList = jsonFilmList;
    }
}

使用ObjectMapper,我可以检索所有电影:

File jsonFile = new File(filePath);
        JsonFilms jsonFilmList = objectMapper.readValue(jsonFile, JsonFilms.class);
rnmwe5a2

rnmwe5a21#

您可以创建适当的类,如FilmActor,并将Json解析为适当的类结构,或者你也可以快速地把它解析成一个Map<String, Object>,你的Map将只包含一个"films"键,它将包含一个List<Map<String, Object>>。你应该遍历这个列表,从列表中的每个Map<String, Object>中提取一个包含List<Map<String, Object>>的关键字"cast",你总结所有这些列表的长度,这就是你的答案。为了将JSON字符串转换为Map<String, Object>,可以使用Jackson库,特别是ObjectMapper类及其方法readValue()或者您可以使用提供JsonUtils类的开放源代码库MgntUtils,它是Jackson库的 Package 器。使用该类解析Json字符串时,其外观如下所示:

Map<String, Object> myMap = null;
try {
      myMap = JsonUtils.readObjectFromJsonString(jsonString, Map.class);
    }
} catch (IOException e) {
   ...
}

可以在here上找到Maven构件的MgntUtils库,可以在Github here上找到作为jar的库以及Javadoc和源代码

2fjabf4q

2fjabf4q2#

如果你只需要标题和演员的名字,你可以使用ObjectMapper.readTree()。因为JsonNode实现了Iterable,你可以使用StreamSupport.stream(node.spliterator(), false)stream所有的值节点。

ObjectMapper mapper = new ObjectMapper();

JsonNode root = mapper.readTree(json);

Map<String, List<String>> filmActors = StreamSupport
        .stream(root.get("films").spliterator(), false)
        .collect(Collectors.toMap(
                filmNode -> filmNode.get("title").asText(),
                filmNode -> StreamSupport
                        .stream(filmNode.get("cast").spliterator(), false)
                        .map(castNode -> castNode.get("actor").asText())
                        .toList()));

filmActors.forEach((title, actors) -> System.out.println(title + ": " 
        + actors.stream().collect(Collectors.joining(", "))));

输出量:

The Fellowship Of The Ring: Billy Boyd, Ian McKellen
Spiderman: Tom Holland
6ju8rftf

6ju8rftf3#

如果允许你添加新的库,那么JsonPath库可以提供帮助。最简单的代码是:

import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;

...

JSONArray result = JsonPath.read(json, "$.films[*].cast[*].actor");

System.out.println("there are " + result.size() + " actors");
System.out.println("they are:");
result.forEach(System.out::println);

相关问题