如何从java 8中的js函数获取数组输出?

时间:2014-09-03 08:51:38

标签: java javascript arrays java-8 nashorn

我在test.js文件中有以下方法:

function avg(input, period) {
var output = []; 
if (input === undefined) {
      return output;
} 
var i,j=0;
 for (i = 0; i < input.length- period; i++) {
    var sum =0;
    for (j = 0; j < period; j++) {
        //print (i+j)
        sum =sum + input[i+j];
        }
    //print (sum + " -- " + sum/period)
    output[i]=sum/period;        
}

 return output;
 }

我想将一个数组从java传递给这个函数,并在java中获取js输出数组。 我使用了以下java代码:

double[] srcC = new double[] { 1.141, 1.12, 1.331, 1.44, 1.751, 1.66, 1.971, 1.88, 1.191, 1.101 };

    try {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("nashorn");

        String location = "test.js";
        engine.eval("load(\"" + location + "\");");
        Invocable invocable = (Invocable) engine;
        // double[] a = (double[]) invocable.invokeFunction("avg", srcC, 2);

        System.out.println("obj " + invocable.invokeFunction("avg", srcC, 2));
    } catch (Exception ex) {
        LOGGER.error(ex.getLocalizedMessage());
    }

我能够看到 avg js 函数的输出,但我不知道如何从java中的js avg函数获取 js输出数组

感谢任何支持。

最诚挚的问候, 奥勒利安

2 个答案:

答案 0 :(得分:7)

Invocable.invokeFunction的返回类型是实现定义的。 Nashorn脚本引擎返回实现jdk.nashorn.api.scripting.JSObject

的对象的实例

此接口有一个方法Collection<Object> values(),因此唯一需要的更改是转换invokeFunction的结果,然后提取值集合:

 JSObject obj = (JSObject)invocable.invokeFunction("avg", srcC, 2);
 Collection result = obj.values();
 for (Object o : result) {
      System.out.println(o);
 }

输出:

1.1305
1.2255
1.3855
1.5955
1.7054999999999998
1.8155000000000001
1.9255
1.5354999999999999

答案 1 :(得分:2)

感谢您的回复。以下代码更好,因为使用java 8 js引擎而不是以前java版本的rhino:

    double[] output = {};
    try {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("nashorn");

        String locationTemp = "D:/test.js";
        engine.eval("load(\"" + locationTemp + "\");");
        Invocable invocable = (Invocable) engine;

        ScriptObjectMirror obj = (ScriptObjectMirror) invocable.invokeFunction("avg",
        input, period);

        Collection<Object> values = obj.values();
        if (values.size() == 0) {
            return output;
        }
        output = new double[values.size()];
        int i = 0;
        for (Iterator<Object> iterator = values.iterator(); iterator.hasNext();) {
            Object value = iterator.next();
            if (value instanceof Double) {
                Double object = (Double) iterator.next();
                output[i] = object;
            }
        }

    } catch (NullPointerException | NoSuchMethodException | ScriptException ex) {
        log.error(ex.getLocalizedMessage());
    }

感谢 ninad 快速回答

最诚挚的问候, Aurelian,