【问题标题】:how to get the array output from a js function in java 8?如何从java 8中的js函数获取数组输出?
【发布时间】:2014-09-03 08:51:37
【问题描述】:

我在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 输出数组

感谢任何支持。

最好的问候, 奥勒良

【问题讨论】:

    标签: java javascript arrays java-8 nashorn


    【解决方案1】:

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

    这个接口有一个方法Collection&lt;Object&gt; 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
    

    【讨论】:

    • 我刚看到你的回答。比我的好。非常感谢
    【解决方案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 的快速回答

    最好的问候, 奥勒良,

    【讨论】:

    • 您拥有 Java 8 - 无需使用显式交互器,只需使用 for (Object value: values) { ... } 就像我在回答中所做的那样。另外,您忘记增加 i ... ;-)
    • 确实...我发现我忘记了增量。再次感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 2019-04-05
    • 2020-02-28
    相关资源
    最近更新 更多