有没有哪个Java 8妙用Nashorn引擎的好例子

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有没有哪个Java 8妙用Nashorn引擎的好例子相关的知识,希望对你有一定的参考价值。

使用Java8,Nashorn大大提高了javascript 引擎引入,以取代现有的Nashorn Java脚本引擎。Nashorn提供2至10倍更好的性能,因为它直接编译代码在存储器,并传递到字节码JVM.Nashorn使用invokedynamics函数,在Java7引入以提高性能。
jjs
对于Nashorn引擎,JAVA8引入了一个新的命令行工具,JJS到控制台执行Java脚本代码。
解读js文件
创建并保存sample.js在 C:> JAVA 文件夹。
sample.jsprint('Hello World!');

打开控制台并使用下面的命令。
C:\JAVA>jjs sample.js

看到结果
Hello World!

JJS在交互模式
打开控制台并使用下面的命令
C:\JAVA>jjs
jjs> print("Hello, World!")
Hello, World!
jjs> quit()
>>

传递参数
打开控制台并使用下面的命令。
C:\JAVA> jjs -- a b c
jjs> print('letters: ' +arguments.join(", "))
letters: a, b, c
jjs>

在JAVA调用JavaScript
使用ScriptEngineManager,JavaScript代码用Java编写可以被调用。
示例
选择使用任何编辑器创建以下java程序在 C:/> JAVA
Java8Tester.javaimport javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

public class Java8Tester
public static void main(String args[])
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
String name = "Mahesh";

Integer result = null;
try
nashorn.eval("print('" + name + "')");
result = (Integer) nashorn.eval("10 + 2");
catch(ScriptException e)
System.out.println("Error executing script: "+ e.getMessage());

System.out.println(result.toString());



验证结果
使用javac编译器编译如下类
C:\JAVA>javac Java8Tester.java

现在运行Java8Tester看到的结果
C:\JAVA>java Java8Tester

看到结果
Mahesh
12

从JavaScript调用Java
下面的例子将展示如何导入和使用Java类的Java脚本。
创建并保存 sample.js 在 c: > JAVA 文件夹.
sample.jsvar BigDecimal = Java.type('java.math.BigDecimal');

function calculate(amount, percentage)
var result = new BigDecimal(amount).multiply(
new BigDecimal(percentage)).divide(
new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
return result.toPlainString();

var result = calculate(568000000000000000023,13.9);
print(result);

打开控制台并使用下面的命令。
C:\JAVA>jjs sample.js

看到结果
78952000000000000003.20
参考技术A 我们在安全模块中使用Nashorn实现规则引擎,安全规则可以很灵活地通过JS脚本配置,而不需要修改发布应用。
稍稍遗憾的地方,一是性能应该还有提升空间(相比较j2v8);二是不支持es6,不过这个关系不大

没有确切的答案:哪个Java Map最便宜?

以前可能有人问过,但是我一次又一次地遇到这种情况,我想存储很少的一些属性,我绝对确定这些属性永远不会超过20个密钥。使用HashMap似乎完全浪费了CPU和内存,而所有开销都从此开始,而且在为每个键查找计算高级哈希值时,性能也很差。如果只有少于20个键(大多数情况下可能更像5个键)。我绝对可以确定,计算哈希值比迭代和比较需要的时间多一百倍……不?

这里有关于过早优化的讨论,但是我在这里并不完全同意。我主要在Android上使用,任何额外的CPU /内存都会为其他内容选择更多功能。不一定在这里谈论消费市场。这里的用例定义非常明确,而且变化不大。万一(永远不会发生的事情)用HashMap替换非常便宜的地图将是微不足道的(突然发生)。

所以,我的问题是;这是我可以在Java中使用的最便宜,最基本的Map?

答案
对于您的第一段:

no!不会有显着的内存开销,因为据我所知,HashMap由16个存储桶初始化,然后每次刷新时其大小都会加倍,因此在最坏的情况下,您的地图会有超过12个存储分区,因此这没什么大不了的。

关于查找时间,它是恒定的,并且等同于访问数组元素的时间,这总是比循环遍历O(n)个元素更好(即使n <20)。 HashMap的唯一背景是未排序,但是就我而言,当我对顺序没有特殊要求时,我认为它是Java中的默认Map实现。

总结:使用HashMap

另一答案
[如果您担心键上的hashCode()计算时间,请考虑缓存计算的值,例如java.lang.String。有关此问题,请参见how caching hashcode works in Java as suggested by Joshua Bloch in effective java?问题。
另一答案
注意:我建议您对过早的优化工作认真对待。对于大多数应用中的大多数程序员而言,我严重怀疑您是否需要担心Map的性能。更重要的是考虑并发,迭代顺序和空值的需求。但是,既然您问了,这就是我的具体答案。

EnumMap

如果键是enums,则最快的Map实现将是EnumMap

基于表示枚举对象域的位图,EnumMap的执行速度非常快,而占用的内存却很少。

EnumMap

如果您真的非常关心性能,请考虑使用IdentityHashMap

IdentityHashMap的此实现使用引用相等而不是对象相等。尽管仍然涉及哈希值,但它是内存中对象地址的哈希值(可以这么说,在Java中我们没有直接的内存访问权限)。因此,完全避免了可能对每个关键对象自己的IdentityHashMap方法进行冗长的调用。因此,性能可能会比Map好。您将看到基本操作(hashCodehashCode)的恒定时间性能。

仔细研究文档,以了解是否要采用这种方法。请注意关于

linear-probe与chaining的讨论,以获得更好的性能。请注意,此类在比较对象时会部分违反HashMap合同,该合同要求使用HashMap方法。而且此映射不提供并发性。


这里是我用来帮助比较与Java 11捆绑在一起的各种get实现的表。

put

以上是关于有没有哪个Java 8妙用Nashorn引擎的好例子的主要内容,如果未能解决你的问题,请参考以下文章

Nashorn——在JDK 8中融合Java与JavaScript之力--转

Nashorn——在JDK 8中融合Java与JavaScript之力

Java_脚本引擎_03_nashorn支持es6

JDK8系列之JavaScript引擎Nashorn

JDK8系列之JavaScript引擎Nashorn

JDK8系列之JavaScript引擎Nashorn