I have written a Java JSON stringifier with the Nashorn API. Since this code is slow, I wanted to ask if I can improve it. My target is the highest possible performance to make it an alternative to other JSON libraries.
JSON.java
package com.example.json;
import java.util.Map;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import com.example.json.util.TextFile;
public class JSON {
private static final Invocable inv = create();
private static final Invocable create() {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
engine.eval(TextFile.readFromResource("/js/json-stringify.js"));
} catch (ScriptException e) {
e.printStackTrace();
}
return (Invocable) engine;
}
public static final String stringify(Map<String, Object> json) {
try {
return (String) inv.invokeFunction("stringifyJSON", json);
} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
}
JSONObject.java
package com.example.json.stringify;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class JSONObject {
private Map<String, Object> map = new HashMap<String, Object>();
public void appendChild(String key, Object object) {
map.put(key, object);
}
public static final Map<String, Object> convertToJavaScript(JSONObject obj) {
return obj.map;
}
}
JSONArray.java
package com.example.json.stringify;
public class JSONArray {
private Object[] array;
public JSONArray(int length) {
array = new Object[length];
}
public void set(int index, Object object) {
if (index >= 0 && index <= array.length - 1) array[index] = object;
}
public static final Object[] convertToJavaScript(JSONArray arr) {
return arr.array;
}
}
/js/json-stringify.js
function stringifyJSON(json) {
var JSONObject = Java.type("com.example.json.stringify.JSONObject");
var JSONArray = Java.type("com.example.json.stringify.JSONArray");
return JSON.stringify(convertJSONObject(json));
function convert(json) {
if (isJSONObject(json)) return convertJSONObject(JSONObject.convertToJavaScript(json));
if (isJSONArray(json)) return convertJSONArray(JSONArray.convertToJavaScript(json));
return json;
}
function convertJSONObject(object) {
var jsobject = {};
for (key in object) {
jsobject[key] = convert(object.get(key));
}
return jsobject;
}
function convertJSONArray(array) {
var jsarray = [];
for (var index = 0, len = array.length; index < len; index++) {
jsarray.push(convert(array[index]));
}
return jsarray;
}
function isJSONObject(json) Object.prototype.toString.call(json) === "[object com.example.json.stringify.JSONObject]";
function isJSONArray(json) Object.prototype.toString.call(json) === "[object com.example.json.stringify.JSONArray]";
}
TextFile.java (from this post)
Example
I used the same example JSON from my JSON parser.
Map<String, Object> json = new HashMap<String, Object>();
JSONArray employees = new JSONArray(3);
JSONObject employee1 = new JSONObject();
employee1.appendChild("firstName", "John");
employee1.appendChild("lastName", "Doe");
employees.set(0, employee1);
JSONObject employee2 = new JSONObject();
employee2.appendChild("firstName", "Anna");
employee2.appendChild("lastName", "Smith");
employees.set(1, employee2);
JSONObject employee3 = new JSONObject();
employee3.appendChild("firstName", "Peter");
employee3.appendChild("lastName", "Jones");
employees.set(2, employee3);
json.put("employees", employees);
System.out.println(JSON.stringify(json));
Result
{"employees":[{"firstName":"John","lastName":"Doe"},{"firstName":"Anna","lastName":"Smith"},{"firstName":"Peter","lastName":"Jones"}]}