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> |
Last active
April 11, 2025 20:57
-
-
Save audinue/48e0fc9d213b0967871400950f8f63f4 to your computer and use it in GitHub Desktop.
Quick, copy-pasteable Java JVM JSON parse/stringify.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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