-
Notifications
You must be signed in to change notification settings - Fork 1
DemoJSAN
JSAN 是JavaScript Array Notation的缩写,用轻量级的文本形式描述数组的结构与取值。
一个最典型的JSAN文本类似于[“1”,2,“three”,true]
JSAN在Java中的实现继承了Iterable接口,并且可以解析/生成JSAN文本。
如果字符串变量String str的值为[“1”,2,“three”,true],可以通过(JSAN)JSON.Parse(CharSequence)方法来解析该字符串,以得到JSAN对象。
// 解析JSAN文本
JSAN jsan = (JSAN) JSON.Parse(str);
通过调用JSAN对象的toString()方法,可以将JSAN对象还原成JSAN文本。
// 输出JSAN文本["1",2,"three",true]
System.out.println("输出JSAN文本:" + jsan.toString());
如果想格式化JSAN文本,则可以调用toString(int)方法,其参数表示缩进字符的个数,通常指定为0。
/* 以0缩进字符输出JSAN文本
[
"1",
2,
"three",
true
]
*/
System.out.println("格式化输出文本:" + jsan.toString(0));
JSAN对象延续了JSON中的attr(String)方法,用以读取某个键对应的属性值(类似于Map的get方法)。
System.out.println("读取id属性:" + jsan.attr("id"));
此外,JSAN对象还可以直接根据非负整数下标读取其中的元素。
System.out.println("读取第0个元素:" + jsan.attr(0));
这里并不一定强制要求传入的参数为int,亦可以是表示非负整数的字符串。
System.out.println("读取第0个元素:" + jsan.attr("0"));
与JSON类似,设置属性的方法则为attr(String,Object),第一个参数为键名,第二个为属性值。
json.attr("id", 2);
System.out.println("设置id属性后:" + json.attr("id"));
JSAN对象还可以对非负整数下标设置对应的元素。
jsan.attr(0, "zero");
或
jsan.attr("0", "zero");
需要注意的是,虽然JSAN与JSON一样,可以将任何普通的字符串作为键,但是非负整数(字符串)键会始终依次存放在普通字符串键之前。如下面的例子中,虽然"strKey"先于"4"设置,但实际存放的结果是,4被存放在JSAN段,并先于strKey被遍历。
System.out.println("不同种类键的顺序:");
jsan.attr("strKey", "Stored as JSON");
jsan.attr("4", "Later set but position before strKey");
for (Pair pair : jsan.pairs())
{
System.out.println(pair.getKey() + " => " + pair.getValue());
}
对非负整数下标对应的元素可以用splice方法对数组元素进行删减、扩充。
System.out.println("用0个元素在位置1处填充2个位置的元素" + jsan.splice(1, 2));
System.out.println("用3个元素在位置1处填充0个位置的元素" + jsan.splice(1, 0, "hey!", 2, false));
attr(String,Object)、attr(int,Object)方法同样支持链式调用。
System.out.println("链式调用attr方法:" + jsan.attr("id", 3).attr(1, "Quene").toString(0));
JSAN会将(任意多维)数组对象换换成JSAN对象。
int[][] arr = new int[][] { { 1, 2, 3 }, { 2, 3, 4 }, { 3, 4, 5 } };
jsan.add(arr);
System.out.println("添加数组元素后:" + jsan.toString());
通过val系列方法读取JSAN元素时可以指定默认值。
System.out.println("以整型读取第5个元素时指定默认值:" + jsan.valInteger(5, 4));
由于JSAN实现了Iterable接口,因此可以按下面的方式遍历其中所有元素。
System.out.println("遍历JSAN中的所有元素:");
for (Object value : jsan)
{
System.out.println(value);
}
JSAN可以通过反射特性读取POJO,POJO中所有通过getter开放的属性都可以被读取。
假如有下面的POJO类
public class DemoPOJO { private int id; private String name; private double value; private Map<String, Object> dict; private float income;
public DemoPOJO() { this.id = 1; this.name = "Joke"; this.value = 1.23; this.dict = new LinkedHashMap<String, Object>(); this.dict.put("one", 1); this.dict.put("two", 2); this.income = 100.1f; }
// JSAN在反射时,会将Map类对象反射为JSAN。 public Map<String, Object> getDict() { return dict; }
public int getId() { return id; }
// 不开放此属性,JSAN将不会反射该数据。 protected float getIncome() { return income; }
public String getName() { return name; }
public double getValue() { return value; } }
DemoPOJO pojo = new DemoPOJO();
JSAN反射对象,默认反射所有字段,并以非负整数下标存放。
DemoPOJO pojo = new DemoPOJO();
jsan.clean().reflect(pojo);
System.out.println("反射读取pojo:" + jsan.toString());
JSAN反射对象中的部分属性。
jsan.clean().reflect(pojo, "id", "name", "value");
System.out.println("反射部分属性:" + jsan.toString());
对反射部分属性并进行映射转换
Map<String, Object> templateMap = new LinkedHashMap<String, Object>();
templateMap.put("2", "id");
templateMap.put("0", "name");
templateMap.put("1", "value");
jsan.clean().reflect(pojo, templateMap);
System.out.println("反射部分属性并映射转换:");
for (Pair pair : jsan.pairs())
{
System.out.println(pair.getKey() + " => " + pair.getValue());
}