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. Android 音视频开发(一):PCM 格式音频的播放与采集

    什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...

  2. 操作系统微内核和Dubbo微内核,有何不同?

    你好,我是 yes. 在之前的文章已经提到了 RPC 的核心,想必一个 RPC 通信大致的流程和基本原理已经清晰了. 这篇文章借着 Dubbo 来说说微内核这种设计思想,不会扯到 Dubbo 某个具体 ...

  3. Spring AOP 实战运用

    Spring AOP 实战 看了上面这么多的理论知识, 不知道大家有没有觉得枯燥哈. 不过不要急, 俗话说理论是实践的基础, 对 Spring AOP 有了基本的理论认识后, 我们来看一下下面几个具体 ...

  4. [LeetCode]654. Maximum Binary Tree最大堆二叉树

    每次找到数组中的最大值,然后递归的构建左右树 public TreeNode constructMaximumBinaryTree(int[] nums) { if (nums.length==0) ...

  5. [leetcode33Search in Rotated Sorted Array]在排序旋转后序列中找目标值

    直接上代码 /** * Created by lvhao on 2017/6/30. * Suppose an array sorted in ascending order is rotated a ...

  6. YourBatman 2020年感悟关键词:科比、裁员、管理层、活着

    目录 本文提纲 ✍前言 版本约定 ✍正文 科比 裁员 如何避免被裁? 1.不要迷恋管理,一味追求"当官" 2.别以为裁员只裁一线,不裁管理层 3.即使步入管理,建议不要脱离技术 4 ...

  7. docker配置mysql实现主从同步问题

    主从同步遇到 Got fatal error 1236 from master when reading data from binary log: 'Could not find first log ...

  8. ElasticSearch教程——分片、扩容以及容错机制(转学习使用)

    一.Primary shard和replica shard机制 1.index包含多个shard; 2.每个shard都是一个最小的工作单元,承载部分的数据,Lucene实例,完整的简历索引和处理请求 ...

  9. 小米11和iPhone11 哪个好

    小米11:搭载最新一代三星的AMOLED屏幕,120Hz屏幕刷新iPhone11采用6.1英寸的分辨率1792828的LCD屏幕小米手机爆降800 优惠力度空前机会不容错过https://www.xi ...

  10. 深入理解Go Context

    目录 emptyCtx类型 cancelCtx类型 timerCtx类型 valueCtx类型 在Go语言并发编程中,用一个goroutine来处理一个任务,而它又会创建多个goroutine来负责不 ...