同一个迭代器一只能迭代一次

同一个迭代器一只能迭代一次,第1张

同一个迭代器一只能迭代一次 一、简单说明

同一个迭代器只能迭代一次,这里我不细说,可以参考这个:
https://blog.csdn.net/weixin_46351306/article/details/113705527

二、功能要求

今天和同事看了一个问题,大概问题如下:
解析yaml文件,并能实现对yaml文件内容进行更改。

三、实现 2.1 引入依赖

      org.yaml
      snakeyaml
      1.21

这是一个可以解析yaml文件内容的包,将yaml的字符串转换为对象,也可将响应的对象转换为字符串。

2.2 相关代码
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import java.util.Iterator;

public class Test {

    //更新YAML配置
    public void updYamlCfg() {
    	
    	//yaml字符串
        String yamlContent = "";

        DumperOptions dumperOptions = new DumperOptions();
        dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        dumperOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
        dumperOptions.setPrettyFlow(false);
        Yaml yaml = new Yaml(dumperOptions);
		
		//将yaml转换为对象迭代器
        Iterable objects = yaml.loadAll(yamlContent);

		//对yaml对象内容做更改
        for (Object object : objects) {
			//略
        }

		//将更改后的迭代器内容转换为字符串
        String newYamlContent2 = yaml.dumpAll(objects.iterator());
        System.out.println(newYamlContent2);
    }
}
 

上述代码实现的功能:
1、将读取到的字符串yaml转换为对象
2、对yaml对象内容进行更改
3、将修改后的对象重新转换为yaml

一开始看到用增强for遍历迭代器,还感觉挺奇怪的,于是点开了编译后的代码看了下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import java.util.Iterator;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.DumperOptions.ScalarStyle;

public class Test {
    public Test() {
    }

    public void updYamlCfg() {
        String yamlContent = "";
        DumperOptions dumperOptions = new DumperOptions();
        dumperOptions.setDefaultFlowStyle(FlowStyle.BLOCK);
        dumperOptions.setDefaultScalarStyle(ScalarStyle.PLAIN);
        dumperOptions.setPrettyFlow(false);
        Yaml yaml = new Yaml(dumperOptions);
        Iterable objects = yaml.loadAll(yamlContent);

        Object var8;
        for(Iterator var7 = objects.iterator(); var7.hasNext(); var8 = var7.next()) {
        }

        String newYamlContent2 = yaml.dumpAll(objects.iterator());
        System.out.println(newYamlContent2);
    }
}

 

原来自动转成了迭代器,不是重点,不关注。

四 、问题出现

按上述逻辑来看,看似没问题,但是运行结果发现,输出为空字符。

最后,点开了dumpAll的源码看到:

    private void dumpAll(Iterator data, Writer output, Tag rootTag) {
        Serializer serializer = new Serializer(new Emitter(output, this.dumperOptions), this.resolver, this.dumperOptions, rootTag);

        try {
            serializer.open();

            while(data.hasNext()) {
                Node node = this.representer.represent(data.next());
                serializer.serialize(node);
            }

            serializer.close();
        } catch (IOException var6) {
            throw new YAMLException(var6);
        }
    }

调用了同一个迭代器的data.hasNext()方法,且一直为false,故此,每次执行更新yaml内容之后,再想输出修改后的对象内容,就总是为空字符串。

五、小结

大家都知道同一个迭代器只能迭代一次,但是往往在开发中忽略了一些方法内部的实现,最后导致一个看似常识的问题却总以不同形式的bug出现。谨记!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5637700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)