yaml与java对象的互转

  1. yaml与java对象的互转有snakeyaml
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>lastest</version>
</dependency>

将map格式化为yml字符串

  1. 通过snakeyaml也可以将map对象转换为yml字符串,但是并不是很适用于平常的配置写法,比如对象会被{}包起来
  2. 通过自写代码将map对象转化为yml字符串
import lombok.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.util.CollectionUtils; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; @Getter
public class YamlTree {
// 测试用例
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("redis.host", "xxx");
map.put("redis.port", "6379");
map.put("redis.auth", "123456");
map.put("redis.lettcue.key[0]", "a");
map.put("redis.lettcue.key[1]", "b");
map.put("redis.lettcue.obj[0].name", "tom");
map.put("redis.lettcue.obj[0].age", "24");
map.put("redis.lettcue.obj[1].name", "sam");
map.put("redis.lettcue.obj[1].age", "21");
YamlTree generate = YamlTree.generate(map);
System.out.println(generate.format());
} private static class Common {
public static String[] fromNext(String[] unParseNodes) {
if (unParseNodes.length > 1) {
String[] copy = new String[unParseNodes.length - 1];
for (int i = 1; i < unParseNodes.length; i++) {
copy[i - 1] = unParseNodes[i];
}
return copy;
}
return null;
} public static void addTreeNode(List<YamlNode> nodes, YamlNode yamlNode) {
boolean contains = false;
for (YamlNode node : nodes) {
if (node.getKey().equals(yamlNode.getKey())) {
contains = true;
break;
}
}
if (!contains) {
nodes.add(yamlNode);
}
} /**
* 返回 是否是数组,数组下标,真实的key
*
* @param key
* @return
*/
public static Triple<Boolean, Integer, String> getRealKey(String key) {
int index = StringUtils.indexOfAny(key, "[", "]");
if (index >= 0) {
int start = StringUtils.indexOf(key, "[");
int end = StringUtils.indexOf(key, "]");
int i = Integer.parseInt(StringUtils
.substring(key, start + 1, end));
key = StringUtils.substring(key, 0, start);
return Triple.of(true, i, key);
}
return Triple.of(false, null, key);
} public static YamlNode findYamlNode(List<YamlNode> nodes, String key) {
Triple<Boolean, Integer, String> triple = getRealKey(key);
for (YamlNode node : nodes) {
if (triple.getRight().equals(node.getKey())) {
return node;
}
}
return null;
}
} public static YamlTree generate(Map<String, Object> map) {
YamlTree yamlTree = new YamlTree();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String unParseKey = entry.getKey();
String[] unParseNodes = StringUtils.split(unParseKey, ".");
findAndAdd(unParseNodes, yamlTree.getNodes(), entry.getValue().toString());
}
return yamlTree;
} private static void findAndAdd(String[] unParseNodes, List<YamlNode> nodes, String value) {
Triple<Boolean, Integer, String> triple = Common.getRealKey(unParseNodes[0]);
String start = triple.getRight();
String[] nextUnParseNodes = Common.fromNext(unParseNodes);
// 先找是否有节点
YamlNode yamlNode = Common.findYamlNode(nodes, start);
// 如果没有节点构造一个新节点
if (yamlNode == null) {
yamlNode = new YamlNode();
yamlNode.setKey(unParseNodes[0]);
yamlNode.autoSet(nextUnParseNodes, value, yamlNode);
Common.addTreeNode(nodes, yamlNode);
} else if (yamlNode.array) {
yamlNode.autoSet(nextUnParseNodes, value, yamlNode);
Common.addTreeNode(nodes, yamlNode);
} else {
// 先继续往下找
findAndAdd(nextUnParseNodes, yamlNode.getNodes(), value);
}
} private List<YamlNode> nodes = new ArrayList<>(); public String format() {
StringBuilder stringBuilder = new StringBuilder();
for (YamlNode node : nodes) {
StringBuilder nodeStringBuilder = new StringBuilder();
node.format(nodeStringBuilder, 0);
stringBuilder.append(nodeStringBuilder.toString());
stringBuilder.append("\n");
}
return stringBuilder.toString();
} @Data
@AllArgsConstructor
@NoArgsConstructor
private static class YamlObjectNode {
private int index;
private Map<String, String> value = new HashMap<>();
} @Getter
private static class YamlNode { private String key; private boolean array; // 临时下标
private int index; private List<YamlObjectNode> objs = new ArrayList<>(); private List<String> values = new ArrayList<>(); private List<YamlNode> nodes = new ArrayList<>(); public void setKey(String key) {
Triple<Boolean, Integer, String> triple = Common.getRealKey(key);
this.key = triple.getRight();
this.array = triple.getLeft();
if (triple.getMiddle() != null) {
this.index = triple.getMiddle();
}
} public void setValue(String value) {
this.values.add(value);
} public YamlNode autoSet(String[] keys, String value, YamlNode last) {
if (keys == null) {
setValue(value);
return this;
}
String start = keys[0];
if (last != null && last.array) {
YamlObjectNode yamlObjectNode = null;
for (YamlObjectNode obj : objs) {
if (obj.getIndex() == index) {
yamlObjectNode = obj;
break;
}
}
boolean newObj = false;
if (yamlObjectNode == null) {
yamlObjectNode = new YamlObjectNode();
newObj = true;
}
yamlObjectNode.setIndex(index);
yamlObjectNode.getValue().put(start, value);
if (newObj) {
objs.add(yamlObjectNode);
}
} else {
YamlNode yamlNode = new YamlNode();
yamlNode.setKey(start);
YamlNode next = yamlNode.autoSet(Common.fromNext(keys), value, yamlNode);
nodes.add(next);
}
return this;
} private void fixBlank(StringBuilder stringBuilder, int level) {
for (int i = 0; i < level; i++) {
stringBuilder.append(" ");
}
} public void format(StringBuilder stringBuilder, int level) {
// 补齐空白
fixBlank(stringBuilder, level);
// 加上key和冒号空格
stringBuilder.append(this.getKey()).append(": ");
if (isArray()) {
// 如果是数组先换行
stringBuilder.append("\n");
// 换行后层级+1
level++;
// 检查是普通数组还是对象数组
if (CollectionUtils.isEmpty(getValues())) {
// 对象数组
List<YamlObjectNode> objs = getObjs();
for (int i = 0; i < objs.size(); i++) {
// 补齐空白
fixBlank(stringBuilder, level);
stringBuilder.append("- ");
Map<String, String> map = objs.get(i).getValue();
int p = 1;
for (Map.Entry<String, String> entry : map.entrySet()) {
if (p == 1) {
stringBuilder.append(entry.getKey() + ": " + entry.getValue()).append("\n");
} else {
fixBlank(stringBuilder, level);
stringBuilder.append(" ");
stringBuilder.append(entry.getKey() + ": " + entry.getValue()).append("\n"); }
p++;
}
}
} else {
// 普通数组
for (String value : getValues()) {
// 补齐空白
fixBlank(stringBuilder, level);
stringBuilder.append("- ").append(value).append("\n");
}
}
} else {
// 如果不是数组
// 检查一下是否有下属节点
if (!CollectionUtils.isEmpty(getValues())) {
stringBuilder.append(getValues().get(0)).append("\n");
} else {
stringBuilder.append("\n");
List<YamlNode> nodes = getNodes();
level++;
for (YamlNode node : nodes) {
node.format(stringBuilder, level);
}
}
}
} } }
  1. 可能写得不怎么样,有很多优化的地方,仅作为记录
  • 关于map key的写法,是参考springcloud属性注入,在内存中的表达形式

Map转换为格式化的YAML字符串的更多相关文章

  1. 使用Python将字符串转换为格式化的日期时间字符串

    我正在尝试将字符串“20091229050936”转换为“2009年12月29日(UTC)” >>>import time >>>s = time.strptime ...

  2. 格式化日期时间字符串 Get-Date -Uformat , -format

    #将字符串格式化为时间格式 $dateTimeStr = '20141231T23:59:59' $format = 'yyyyMMddTHH:mm:ss' $formatProvider = [Gl ...

  3. 中文字符串转换为十六进制Unicode编码字符串

    package my.unicode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Uni ...

  4. golang 格式化时间为字符串

    package main import ( "fmt" "reflect" "time" ) func main() { //格式化字符串为 ...

  5. 将32位MD5摘要串转换为128位二进制字符串

    将32为MD5摘要串转换为128位二进制字符串: /// <summary> /// 将字符串转成二进制 /// </summary> /// <param name=& ...

  6. 浮点数转换为人名币读法字符串(JAVA)

    /*<java疯狂讲义>浮点数转换为人名币读法字符串这个用例,感觉没有考虑零的情况*/ import java.util.Arrays; public class Num2Rmb { pr ...

  7. java中把字节数组转换为16进制字符串

    把字符串数组转换为16进制字符串 import java.security.MessageDigest; public class StringUtil { public StringUtil() { ...

  8. Python第二天 变量 运算符与表达式 input()与raw_input()区别 字符编码 python转义符 字符串格式化 format函数字符串格式化 帮助

    Python第二天  变量  运算符与表达式  input()与raw_input()区别  字符编码  python转义符  字符串格式化  format函数字符串格式化  帮助 目录 Pychar ...

  9. 利用JSON将Map转换为类对象

    Map类型做为一种常见的Java类型,经常在开发过程中使用,笔者最近遇到要将Map对象做为一种通用的参数变量,下传到多个业务类方法中,然后在各个业务类方法中将Map转换为指定类对象的情况.如何将Map ...

随机推荐

  1. [leetcode]29. Divide Two Integers不用除法实现除法

    思路是不断将被除数分为两部分,每次分的一部分都是尽量大的除数的倍数,然后最后的商就是倍数加上剩下的部分再分,知道不够大. 递归实现 剩下的难点就是,正负号(判断商正负后将两个数都取绝对值),数太大(将 ...

  2. libzip开发笔记(一):libzip库介绍、编译和工程模板

      前言   Qt使用一些压缩解压功能,选择libzip库,libzip库比较原始,也是很多其他库的基础支撑库.   libzip   libzip是一个C库,用于读取,创建和修改zip档案.可以从数 ...

  3. Python将GIF图片转换成png图片帧

    效果图: 转换之后保存到文件夹中: 代码如下:(第三方库pillow,安装方法:在cmd中输入:  pip install pillow) from PIL import Image import o ...

  4. JSP 的 4 种作用域?

    page:代表与一个页面相关的对象和属性. request:代表与客户端发出的一个请求相关的对象和属性.一个请求可能跨越多个页面,涉及多个 Web 组件:需要在页面显示的临时数据可以置于此作用域. s ...

  5. 对CAS中atomicInteger实现的思考

    p.p1 { margin: 0; font: 11px Monaco } span.s1 { color: rgba(147, 26, 104, 1) } span.s2 { color: rgba ...

  6. count(*) 优化

    几种获取记录数的方法 count(*): MySQL 优化过,扫描的行数小于总记录数.执行效率高. count(1): 遍历所有记录,不取值,对每行尝试添加一个 "1" 列,如果不 ...

  7. JButton的常用方法

    JButton 实现了普通的三态外加选中.禁用状态,有很多方法可以设置,不要自己去写鼠标监听器.setBorderPainted(boolean b)    //是否画边框,如果用自定义图片做按钮背景 ...

  8. idea生成UML

    原文链接http://zhhll.icu/2020/12/18/idea/%E7%94%9F%E6%88%90UML/ 使用idea直接生成UML类图 然后点击所要生成的类即可生成 由于本身的博客百度 ...

  9. Harbor镜像删除回收?只看这篇

    最近,公司的技术平台,运维的破事儿颇多.Jira无法访问,ES堆内存不足,Jenkins频繁不工作..等等等,让我这个刚入门的小兵抓心脑肝,夜不能寐,关键时刻方恨经验薄弱呀!!一波未平,一波又起,这不 ...

  10. 跨域的几种方式以及call(),apply() bind()方法的作用和区别

    jsonp: jsonp 全称是JSON with Padding,是为了解决跨域请求资源而产生的解决方案,是一种依靠开发人员创造出的一种非官方跨域数据交互协议. 一个是描述信息的格式,一个是信息传递 ...