概述
一、简单说明
同一个迭代器只能迭代一次,这里我不细说,可以参考这个:
https://blog.csdn.net/weixin_46351306/article/details/113705527
二、功能要求
今天和同事看了一个问题,大概问题如下:
解析yaml文件,并能实现对yaml文件内容进行更改。
三、实现
2.1 引入依赖
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.21</version>
</dependency>
这是一个可以解析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<Object> 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<Object> 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<? extends Object> 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出现。谨记!
最后
以上就是独特冥王星为你收集整理的同一个迭代器一只能迭代一次一、简单说明二、功能要求三、实现四 、问题出现五、小结的全部内容,希望文章能够帮你解决同一个迭代器一只能迭代一次一、简单说明二、功能要求三、实现四 、问题出现五、小结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复