Skip to content

Instantly share code, notes, and snippets.

@audinue
Last active April 11, 2025 20:57
Show Gist options
  • Save audinue/48e0fc9d213b0967871400950f8f63f4 to your computer and use it in GitHub Desktop.
Save audinue/48e0fc9d213b0967871400950f8f63f4 to your computer and use it in GitHub Desktop.
Quick, copy-pasteable Java JVM JSON parse/stringify.

image

Type Mapping

JSON Type Java Type
null null
true true
false false
number java.lang.Double
string java.lang.String
array java.util.List<Object>
object java.util.Map<String, Object>
@SuppressWarnings("unchecked")
class JSON {
static Object parse(String string) {
return parse(java.util.regex.Pattern.compile(
"\\s+|null|true|false|-?[0-9]+(\\.[0-9]+)?([Ee][-+]?[0-9]+)?|\"(\\\\.|[^\\\"])*\"|,|\\:|\\[|\\]|\\{|\\}"
).matcher(string));
}
private static Object COMMA = new Object();
private static Object COLON = new Object();
private static Object SQUARE = new Object();
private static Object CURLY = new Object();
private static Object parse(java.util.regex.Matcher matcher) {
if (!matcher.find()) {
throw new IllegalArgumentException();
}
String group = matcher.group();
if (Character.isWhitespace(group.charAt(0))) {
return parse(matcher);
} else if (group.equals("null")) {
return null;
} else if (group.equals("true")) {
return true;
} else if (group.equals("false")) {
return false;
} else if (group.startsWith("-") || Character.isDigit(group.charAt(0))) {
return Double.parseDouble(group);
} else if (group.startsWith("\"")) {
String result = "";
for (int i = 1; i < group.length() - 1; i++) {
char c = group.charAt(i);
if (c == '\\') {
c = group.charAt(++i);
switch (c) {
case '\\':
case '"': result += c; break;
case 't': result += '\t'; break;
case 'r': result += '\r'; break;
case 'n': result += '\n'; break;
case 'b': result += '\b'; break;
case 'f': result += '\f'; break;
case 'u':
result += (char) Integer.parseInt(group.substring(i + 1, i + 5), 16);
i += 4;
break;
default:
throw new IllegalArgumentException();
}
} else {
result += c;
}
}
return result;
} else if (group.equals(",")) {
return COMMA;
} else if (group.equals(":")) {
return COLON;
} else if (group.equals("]")) {
return SQUARE;
} else if (group.equals("}")) {
return CURLY;
} else if (group.equals("[")) {
java.util.List<Object> result = new java.util.ArrayList<>();
while (true) {
Object next = parse(matcher);
if (next == COMMA) {
continue;
}
if (next == SQUARE) {
break;
}
result.add(next);
}
return result;
} else if (group.equals("{")) {
java.util.Map<Object, Object> result = new java.util.LinkedHashMap<>();
while (true) {
Object key = parse(matcher);
if (key == COMMA) {
continue;
}
if (key == CURLY) {
break;
}
Object colon = parse(matcher);
if (colon != COLON) {
throw new IllegalArgumentException();
}
result.put(key, parse(matcher));
}
return result;
} else {
throw new IllegalArgumentException();
}
}
static String stringify(Object value) {
if (value == null) {
return "null";
} else if (value instanceof Boolean) {
return value.toString();
} else if (value instanceof Double) {
return value.toString();
} else if (value instanceof String) {
String string = (String) value;
String result = "\"";
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
switch (c) {
case '"': result += "\\\""; break;
case '\\': result += "\\\\"; break;
case '\t': result += "\\t"; break;
case '\r': result += "\\r"; break;
case '\n': result += "\\n"; break;
case '\b': result += "\\b"; break;
case '\f': result += "\\f"; break;
default:
if (c < 0x20 || c > 0x7E) {
String s = Integer.toHexString(c);
result += "\\u" + "0000".substring(s.length()) + s;
} else {
result += c;
}
}
}
return result + "\"";
} else if (value instanceof java.util.List) {
java.util.List<Object> list = (java.util.List<Object>) value;
String result = "[";
boolean next = false;
for (Object item : list) {
if (next) {
result += ",";
} else {
next = true;
}
result += stringify(item);
}
return result + "]";
} else if (value instanceof java.util.Map) {
java.util.Map<Object, Object> map = (java.util.Map<Object, Object>) value;
String result = "{";
boolean next = false;
for (java.util.Map.Entry<Object, Object> entry : map.entrySet()) {
if (next) {
result += ",";
} else {
next = true;
}
result += stringify(entry.getKey()) + ":" + stringify(entry.getValue());
}
return result + "}";
} else {
throw new IllegalArgumentException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment