⚠️ 测试版状态 (v1.x.x): 此库正处于积极开发中,并致力于符合规范。测试版已发布到Maven中央仓库。在2.0.0版本发布之前,API可能会发生变化。
紧凑且易于人类阅读的LLM上下文序列化格式,与JSON相比,可减少**30-60%**的标记。结合了类似YAML的缩进和类似CSV的表格数组。正致力于实现与官方TOON规范的完全兼容性。
关键特性: 最小语法 • TOON编码和解码 • 表格数组用于统一数据 • 数组长度验证 • Java 17 • 全面的测试覆盖。
JToon可在Maven中央仓库获取。使用您喜欢的构建工具将其添加到您的项目中:
Gradle (Groovy DSL):
dependencies {
implementation 'dev.toonformat:jtoon:1.0.5'
}
Gradle (Kotlin DSL):
dependencies {
implementation("dev.toonformat:jtoon:1.0.5")
}
Maven:
<dependency>
<groupId>dev.toonformat</groupId>
<artifactId>jtoon</artifactId>
<version>1.0.5</version>
</dependency>
注意: 查看Maven中央仓库上的最新版本(也显示在上面的徽章中)。
您也可以从GitHub Releases页面直接下载JAR文件,并将其添加到项目的类路径中。
import dev.toonformat.jtoon.JToon;
import java.util.*;
record User(int id, String name, List<String> tags, boolean active, List<?> preferences) {}
record Data(User user) {}
User user = new User(123, "Ada", List.of("reading", "gaming"), true, List.of());
Data data = new Data(user);
System.out.println(JToon.encode(data));
输出:
user:
id: 123
name: Ada
tags[2]: reading,gaming
active: true
preferences[0]:
一些Java特定类型会自动规范化以生成适合LLM的输出:
| 输入类型 | 输出 |
|---|---|
| 数字(有限) | 十进制形式;-0 → 0;整数作为整数 |
数字(NaN,±Infinity) | null |
BigInteger | 如果在Long范围内,则为整数,否则为字符串(无引号) |
BigDecimal | 十进制数字 |
LocalDateTime | 引号内的ISO日期时间字符串 |
LocalDate | 引号内的ISO日期字符串 |
LocalTime | 引号内的ISO时间字符串 |
ZonedDateTime | 引号内的ISO时区日期时间字符串 |
OffsetDateTime | 引号内的ISO偏移日期时间字符串 |
Instant | 引号内的ISO瞬间字符串 |
java.util.Date | 引号内的ISO瞬间字符串 |
Optional<T> | 如果为空则为未包装值或null |
Stream<T> | 实现为数组 |
Map | 字符串键的对象 |
Collection,数组 | 数组 |
JToon.encode(Object value): StringJToon.encode(Object value, EncodeOptions options): StringJToon.encodeJson(String json): StringJToon.encodeJson(String json, EncodeOptions options): String将任何Java对象或JSON字符串转换为TOON格式。
参数:
value – 任何Java对象(Map,List,原始类型或嵌套结构)。不可序列化的值将转换为null。Java时间类型将转换为ISO字符串,Optional将被解开,Stream将被实现。options – 可选的编码选项(EncodeOptions记录):
indent – 每个缩进级别的空格数(默认:2)delimiter – 数组值和表格行的分隔符枚举:Delimiter.COMMA(默认),Delimiter.TAB,或Delimiter.PIPElengthMarker – 布尔值,表示是否在数组长度前加上#(默认:false)对于encodeJson重载:
json – 要解析并编码的有效JSON字符串。无效或空白的JSON将抛出IllegalArgumentException。返回:
一个没有尾随换行符或空格的TOON格式字符串。
示例:
import dev.toonformat.jtoon.JToon;
import java.util.*;
record Item(String sku, int qty, double price) {}
record Data(List<Item> items) {}
Item item1 = new Item("A1", 2, 9.99);
Item item2 = new Item("B2", 1, 14.5);
Data data = new Data(List.of(item1, item2));
System.out.println(JToon.encode(data));
输出:
items[2]{sku,qty,price}:
A1,2,9.99
B2,1,14.5
String json = """
{
"user": {
"id": 123,
"name": "Ada",
"tags": ["reading", "gaming"]
}
}
""";
System.out.println(JToon.encodeJson(json));
输出:
user:
id: 123
name: Ada
tags[2]: reading,gaming
delimiter选项允许您选择逗号(默认)、制表符或竖线分隔符来分隔数组值和表格行。替代分隔符可以在特定情况下提供额外的标记节省。
\t)使用制表符而不是逗号可以进一步减少标记数量,特别是在表格数据中:
import dev.toonformat.jtoon.*;
import java.util.*;
record Item(String sku, String name, int qty, double price) {}
record Data(List<Item> items) {}
Item item1 = new Item("A1", "Widget", 2, 9.99);
Item item2 = new Item("B2", "Gadget", 1, 14.5);
Data data = new Data(List.of(item1, item2));
EncodeOptions options = new EncodeOptions(2, Delimiter.TAB, false);
System.out.println(JToon.encode(data, options));
输出:
items[2 ]{sku name qty price}:
A1 Widget 2 9.99
B2 Gadget 1 14.5
优点:
注意事项:
|)竖线分隔符提供了介于逗号和制表符之间的中间地带:
// 使用上面相同的Item和Data记录
EncodeOptions options = new EncodeOptions(2, Delimiter.PIPE, false);
System.out.println(JToon.encode(data, options));
输出:
items[2|]{sku|name|qty|price}:
A1|Widget|2|9.99
B2|Gadget|1|14.5
lengthMarker选项在数组长度前添加一个可选的哈希(#)前缀,以强调括号内的值代表计数,而非索引:
import dev.toonformat.jtoon.*;
import java.util.*;
record Item(String sku, int qty, double price) {}
record Data(List<String> tags, List<Item> items) {}
Item item1 = new Item("A1", 2, 9.99);
Item item2 = new Item("B2", 1, 14.5);
Data data = new Data(List.of("reading", "gaming", "coding"), List.of(item1, item2));
System.out.println(JToon.encode(data, new EncodeOptions(2, Delimiter.COMMA, true)));
// tags[#3]: reading,gaming,coding
// items[#2]{sku,qty,price}:
// A1,2,9.99
// B2,1,14.5
// 适用于自定义分隔符
System.out.println(JToon.encode(data, new EncodeOptions(2, Delimiter.PIPE, true)));
// tags[#3|]: reading|gaming|coding
// items[#2|]{sku|qty|price}:
// A1|2|9.99
// B2|1|14.5
JToon.decode(String toon): ObjectJToon.decode(String toon, DecodeOptions options): ObjectJToon.decodeToJson(String toon): StringJToon.decodeToJson(String toon, DecodeOptions options): String将TOON格式字符串转换回Java对象或JSON。
参数:
toon – TOON格式输入字符串options – 可选的解码选项(DecodeOptions记录):
indent – 每个缩进级别的空格数(默认:2)delimiter – 预期的分隔符:Delimiter.COMMA(默认),Delimiter.TAB,或Delimiter.PIPEstrict – 验证模式的布尔值。当true(默认)时,在输入无效时抛出IllegalArgumentException。当false时,在错误时返回null。返回:
对于decode: Java对象(对象为Map,数组为List,标量为原始类型,或null)
对于decodeToJson: JSON字符串表示
示例:
import dev.toonformat.jtoon.JToon;
String toon = """
users[2]{id,name,role}:
1,Alice,admin
2,Bob,user
""";
// 解码为Java对象
Object result = JToon.decode(toon);
// 直接解码为JSON字符串
String json = JToon.decodeToJson(toon);
import dev.toonformat.jtoon.*;
import java.util.*;
// 原始数据
Map<String, Object> data = new LinkedHashMap<>();
data.put("id", 123);
data.put("name", "Ada");
data.put("tags", Arrays.asList("dev", "admin"));
// 编码为TOON
String toon = JToon.encode(data);
// 解码回对象
Object decoded = JToon.decode(toon);
// 值得以保存(注意:整数解码为Long)
import dev.toonformat.jtoon.*;
String toon = "tags[3|]: a|b|c";
// 使用竖线分隔符解码
DecodeOptions options = new DecodeOptions(2, Delimiter.PIPE, true);
Object result = JToon.decode(toon, options);
// 宽容模式(在错误时返回null而不是抛出异常)
DecodeOptions lenient = DecodeOptions.withStrict(false);
Object result2 = JToon.decode(invalidToon, lenient);
CI/CD: GitHub Actions • Java 17 • 覆盖率强制执行 • PR覆盖率评论
此项目完全符合TOON规范。发布一致性在CI/CD中强制执行。
查看CONTRIBUTING.md以获取详细指南。
MIT许可 – 详情见LICENSE