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. CODING 静态网站服务升级,快速、稳定、高拓展!

    CODING 静态网站拥有强大的页面托管服务,目前已有数万开发者.设计师.产品经理.团队与企业使用 CODING 静态网站托管了他(她)们的个人网站.博客.企业与产品官网.在线文档等.CODING 静 ...

  2. [leetcode]120.Triangle三角矩阵从顶到底的最小路径和

    Given a triangle, find the minimum path sum from top to bottom.Each step you may move to adjacent nu ...

  3. Mac电脑远程连接SSH Host key verification failed 解决办法

    苹果电脑远程连接SSH出现如下问题: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     ...

  4. 相对于Statement,PreparedStatement的优点是什么?

    优点: 1.PreparedStatement有助于防止SQL注入,因为它会自动对特殊字符转义. 2.PreparedStatement可以用来进行动态查询. 3.PreparedStatement执 ...

  5. VNC使用及其常见问题解决方法

    博主之前在博文(https://www.cnblogs.com/kangbazi666/p/14153604.html)中已经介绍了多人VNC的配置方法,下面将简单介绍其使用方法及常见问题的解决方法. ...

  6. Windows10搭建本地ftp服务器

    首先要有一个win10专业版的操作系统,连接上互联网... 一.首先打开控制面板选择程序,再选择"启用或关闭windows功能" 二.在"Windows功能"中 ...

  7. java类的主动使用/被动使用

    对类的使用方式分为:主动使用.被动使用 所有的java虚拟机实现必须在每个类或接口被java程序"首次主动使用"时才初始化他们 ps:被动使用不会初始化类,但是有可能会加载类(JV ...

  8. [剑指 Offer 18. 删除链表的节点]

    [剑指 Offer 18. 删除链表的节点] 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head ...

  9. CountDownLatch/CyclicBarrier/Semaphore 使用过吗

    CountDownLatch 让一些线程堵塞直到另一个线程完成一系列操作后才被唤醒.CountDownLatch 主要有两个方法,当一个或多个线程调用 await 方法时,调用线程会被堵塞,其他线程调 ...

  10. Apache伪静态(Rewrite).htaccess文件详解

    Htaccess(超文本访问)是一个简单的配置文件,它允许设计师,开发者和程序员通过它来改变Apache Web服务器的配置.这些功能包括用户重定向.URL重写(url rewrite,国内很多称为伪 ...