Java迭代器和流

时间:2016-12-23 14:27:16

标签: java java-8 java-stream

我正在尝试将我已经创建的循环转换为Java流,尽管代码使用iterators并且我发现很难将其转换为可读代码。

private void printKeys() throws IOException {
    ClassLoader classLoader = getClass().getClassLoader();

    // read a json file
    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode root = objectMapper.readTree(classLoader.getResource("AllSets.json"));
    Set<String> names = new HashSet<>();

    // loop through each sub node and store the keys
    for (JsonNode node : root) {
        for (JsonNode cards : node.get("cards")) {
            Iterator<String> i = cards.fieldNames();
            while(i.hasNext()){
                String name = i.next();
                names.add(name);
            }
        }
    }

    // print each value
    for (String name : names) {
        System.out.println(name);
    }

   }

我尝试了下面的内容,但我觉得它不是正确的方式。

List<JsonNode> nodes = new ArrayList<>();
root.iterator().forEachRemaining(nodes::add);

Set<JsonNode> cards = new HashSet<>();
nodes.stream().map(node -> node.get("cards")).forEach(cards::add);

Stream s = StreamSupport.stream(cards.spliterator(), false);
//.. unfinished and unhappy

你可以找到我在这里使用的Json文件:https://mtgjson.com/json/AllSets.json.zip 警告它非常大。

3 个答案:

答案 0 :(得分:3)

你可以一举完成大部分事情,但遗憾的是这个json api不能更好地支持流。

List<JsonNode> nodes = new ArrayList<>();
root.iterator().forEachRemaining(nodes::add);

Set<String> names = nodes.stream()
    .flatMap(node -> StreamSupport.stream(
        node.get("cards").spliterator(), false))
    .flatMap(node -> StreamSupport.stream(
        ((Iterable<String>) () -> node.fieldNames()).spliterator(), false))
    .collect(Collectors.toSet());

或者使用Patrick的助手方法(来自评论):

Set<String> names = stream(root)
    .flatMap(node -> stream(node.get("cards")))
    .flatMap(node -> stream(() -> node.fieldNames()))
    .collect(Collectors.toSet());

...

public static <T> Stream<T> stream(Iterable<T> itor) {
    return StreamSupport.stream(itor.spliterator(), false);
}

打印:

names.stream().forEach(System.out::println);

答案 1 :(得分:0)

如果您向我们提供'json'文件,那将非常有用。

至少现在,我可以向你提出一些建议:

Set<JsonNode> cards = new HashSet<>();
nodes.stream().map(node -> node.get("cards")).forEach(cards::add);

替换为:

Set<JsonNode> cards = nodes.stream().map(node -> node.get("cards")).collect(Collectors.toSet());
for (String name : names) {
    System.out.println(name);
}

替换为:

names.forEach(System.out::println);

答案 2 :(得分:0)

替换

Set<JsonNode> cards = new HashSet<>();

List<JsonNode> cards = new ArrayList<>();

删除

Stream s = StreamSupport.stream(cards.spliterator(), false);

然后添加以下行

cards.stream().forEach( card -> {
    Iterable<String> iterable = () -> card.fieldNames();
    Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);
    targetStream.forEach(names::add);
});
names.forEach(System.out::println);