Map转换为格式化的YAML字符串
yaml与java对象的互转
- yaml与java对象的互转有snakeyaml
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>lastest</version>
</dependency>
将map格式化为yml字符串
- 通过snakeyaml也可以将map对象转换为yml字符串,但是并不是很适用于平常的配置写法,比如对象会被{}包起来
- 通过自写代码将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);
}
}
}
}
}
}
- 可能写得不怎么样,有很多优化的地方,仅作为记录
- 关于map key的写法,是参考springcloud属性注入,在内存中的表达形式
Map转换为格式化的YAML字符串的更多相关文章
- 使用Python将字符串转换为格式化的日期时间字符串
我正在尝试将字符串“20091229050936”转换为“2009年12月29日(UTC)” >>>import time >>>s = time.strptime ...
- 格式化日期时间字符串 Get-Date -Uformat , -format
#将字符串格式化为时间格式 $dateTimeStr = '20141231T23:59:59' $format = 'yyyyMMddTHH:mm:ss' $formatProvider = [Gl ...
- 中文字符串转换为十六进制Unicode编码字符串
package my.unicode; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Uni ...
- golang 格式化时间为字符串
package main import ( "fmt" "reflect" "time" ) func main() { //格式化字符串为 ...
- 将32位MD5摘要串转换为128位二进制字符串
将32为MD5摘要串转换为128位二进制字符串: /// <summary> /// 将字符串转成二进制 /// </summary> /// <param name=& ...
- 浮点数转换为人名币读法字符串(JAVA)
/*<java疯狂讲义>浮点数转换为人名币读法字符串这个用例,感觉没有考虑零的情况*/ import java.util.Arrays; public class Num2Rmb { pr ...
- java中把字节数组转换为16进制字符串
把字符串数组转换为16进制字符串 import java.security.MessageDigest; public class StringUtil { public StringUtil() { ...
- Python第二天 变量 运算符与表达式 input()与raw_input()区别 字符编码 python转义符 字符串格式化 format函数字符串格式化 帮助
Python第二天 变量 运算符与表达式 input()与raw_input()区别 字符编码 python转义符 字符串格式化 format函数字符串格式化 帮助 目录 Pychar ...
- 利用JSON将Map转换为类对象
Map类型做为一种常见的Java类型,经常在开发过程中使用,笔者最近遇到要将Map对象做为一种通用的参数变量,下传到多个业务类方法中,然后在各个业务类方法中将Map转换为指定类对象的情况.如何将Map ...
随机推荐
- [leetcode]29. Divide Two Integers不用除法实现除法
思路是不断将被除数分为两部分,每次分的一部分都是尽量大的除数的倍数,然后最后的商就是倍数加上剩下的部分再分,知道不够大. 递归实现 剩下的难点就是,正负号(判断商正负后将两个数都取绝对值),数太大(将 ...
- libzip开发笔记(一):libzip库介绍、编译和工程模板
前言 Qt使用一些压缩解压功能,选择libzip库,libzip库比较原始,也是很多其他库的基础支撑库. libzip libzip是一个C库,用于读取,创建和修改zip档案.可以从数 ...
- Python将GIF图片转换成png图片帧
效果图: 转换之后保存到文件夹中: 代码如下:(第三方库pillow,安装方法:在cmd中输入: pip install pillow) from PIL import Image import o ...
- JSP 的 4 种作用域?
page:代表与一个页面相关的对象和属性. request:代表与客户端发出的一个请求相关的对象和属性.一个请求可能跨越多个页面,涉及多个 Web 组件:需要在页面显示的临时数据可以置于此作用域. s ...
- 对CAS中atomicInteger实现的思考
p.p1 { margin: 0; font: 11px Monaco } span.s1 { color: rgba(147, 26, 104, 1) } span.s2 { color: rgba ...
- count(*) 优化
几种获取记录数的方法 count(*): MySQL 优化过,扫描的行数小于总记录数.执行效率高. count(1): 遍历所有记录,不取值,对每行尝试添加一个 "1" 列,如果不 ...
- JButton的常用方法
JButton 实现了普通的三态外加选中.禁用状态,有很多方法可以设置,不要自己去写鼠标监听器.setBorderPainted(boolean b) //是否画边框,如果用自定义图片做按钮背景 ...
- idea生成UML
原文链接http://zhhll.icu/2020/12/18/idea/%E7%94%9F%E6%88%90UML/ 使用idea直接生成UML类图 然后点击所要生成的类即可生成 由于本身的博客百度 ...
- Harbor镜像删除回收?只看这篇
最近,公司的技术平台,运维的破事儿颇多.Jira无法访问,ES堆内存不足,Jenkins频繁不工作..等等等,让我这个刚入门的小兵抓心脑肝,夜不能寐,关键时刻方恨经验薄弱呀!!一波未平,一波又起,这不 ...
- 跨域的几种方式以及call(),apply() bind()方法的作用和区别
jsonp: jsonp 全称是JSON with Padding,是为了解决跨域请求资源而产生的解决方案,是一种依靠开发人员创造出的一种非官方跨域数据交互协议. 一个是描述信息的格式,一个是信息传递 ...