Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nashorn,Java集合,如何在纯javascript中实现equals和hashCode_Java_Javascript_Equals_Hashcode_Nashorn - Fatal编程技术网

Nashorn,Java集合,如何在纯javascript中实现equals和hashCode

Nashorn,Java集合,如何在纯javascript中实现equals和hashCode,java,javascript,equals,hashcode,nashorn,Java,Javascript,Equals,Hashcode,Nashorn,我面临着以下问题。我想在Nashorn脚本中使用java.util.HashMap和java.util.PriorityQueue,其中我需要使用特定的自定义对象作为HashMap中的键,还需要使用HashMap.containsKey()检查映射中是否有键(另一个选项是检查集合中的对象是否包含)(对象(o)) 所以,很明显,我需要基于一些字段值在对象中实现equals和hashCode 例如: 试图使用JavaScript。由于JavaScript没有这些方法,因此无法工作。请参阅示例1和示例

我面临着以下问题。我想在Nashorn脚本中使用
java.util.HashMap
java.util.PriorityQueue
,其中我需要使用特定的自定义对象作为HashMap中的键,还需要使用
HashMap.containsKey()
检查映射中是否有键(另一个选项是检查集合中的对象是否包含)(对象(o))

所以,很明显,我需要基于一些字段值在对象中实现equals和hashCode

例如:

  • 试图使用JavaScript。由于JavaScript没有这些方法,因此无法工作。请参阅示例1示例2

  • 扩展java.lang.Object.示例3部分有效,正在调用方法

    • 如何使用参数插入构造函数
    • 如何从这个:[object]转换到其他:jdk.nashorn.javaadapters.java.lang。Object@0,反之亦然
  • 用Java实现我的自定义类并用JavaScript扩展它。示例4很有效。但是如果我必须使用Java,我需要Nashorn吗

  • var PriorityQueue=java.util.PriorityQueue;
    var HashMap=java.util.HashMap;
    var Integer=java.lang.Integer;
    //样本1
    //不起作用,没有调用equals和hashCode
    函数顶点1(起始、成本){
    this.from=from;
    成本=成本;
    this.equals=函数(其他){返回this.from==other.from;}
    this.hashCode=function(){返回整数.hashCode(this.from);}
    }
    var hm=新的HashMap();
    hm.put(新顶点1(1,10),10);
    hm.put(新顶点1(1,20),21);
    //照片尺寸是2号,但我想看1号
    打印(“哈希映射大小:+hm.size());
    //打印错误
    打印(“HashMap1包含:”+hm.containsKey(新的顶点1(1,20)));
    // ------------------------------------------------------------------
    //样本2
    //不起作用,没有调用equals和hashCode
    函数顶点1(起始、成本){
    this.from=from;
    成本=成本;
    }
    Vertex1.prototype={
    等于:函数(其他){返回this.from==other.from;},
    hashCode:function(){return Integer.hashCode(this.from);},
    }
    var hm=新的HashMap();
    hm.put(新顶点1(1,10),10);
    hm.put(新顶点1(1,20),21);
    //照片尺寸是2号,但我想看1号
    打印(“哈希映射大小:+hm.size());
    //打印错误
    打印(“HashMap1包含:”+hm.containsKey(新的顶点1(1,20)));
    // ------------------------------------------------------------------
    //样本3
    //部分工作,正在调用方法。但是
    //1.如何使用参数插件Constructor?
    //2.如何从这个:[object]转换到其他:jdk.nashorn.javaadapters.java.lang。Object@0,反之亦然
    var JObject=Java.type(“Java.lang.Object”);
    var Vertex2=Java.extend(JObject{
    起:0,,
    equals:function(other){返回this.from.equals(other.from);},
    hashCode:function(){return Integer.hashCode(this.from);},
    });
    var hm=新的HashMap();
    //如何为新的顶点2(10,10)实现构造函数?
    hm.put(新顶点2(),10);
    hm.put(新顶点2(),21);
    //打印大小为2,因为hashCode相同且等于返回false
    打印(“哈希映射大小:+hm.size());
    //打印false,因为equals返回false
    打印(“HashMap1包含:”+hm.containsKey(新的顶点2()));
    // ------------------------------------------------------------------
    //样本4
    //MyObject是用Java实现的,可以工作,但是Nashorn是不明确的!!!
    var MyObject=Java.type(“com.arsenyko.MyObject”);
    var Vertex2=Java.extend(MyObject,{});
    var hm=新的HashMap();
    hm.put(新顶点2(1,10,10);
    hm.put(新顶点2(1,20,21);
    打印(“哈希映射大小:+hm.size());
    打印(“HashMap1包含:”+hm.containsKey(新的顶点2(1,10)));
    
    编辑1

    @Tomasz,谢谢。已经看到了所有提到的链接。但是尽管存在一些未记录的链接。几乎放弃了Nashorn。到了下面的部分解决方案,调用了方法,使用了构造函数,但是如何在
    方法中强制转换
    其他。from
    等于
    方法,以便从访问
    原始对象的ode>字段(此代码为顶点的每个实例生成不同的类):

    //加载(“nashorn:mozilla_compat.js”);
    var PriorityQueue=java.util.PriorityQueue;
    var HashMap=java.util.HashMap;
    var Integer=java.lang.Integer;
    函数顶点1(起始、成本){
    this.from=from;
    成本=成本;
    this.equals=函数(其他){
    var value1=此值为从;
    //如何从这里得到其他的???
    var值2=其他来源;
    打印('value1='+value1+'value2='+value2);
    印刷品(其他);
    var eq=值1。等于(值2);
    打印('equals is'+eq);
    返回均衡器;
    }
    this.hashCode=函数(){
    var hashCode=Integer.hashCode(this.from);
    打印('hashCode为'+hashCode');
    返回哈希码;
    }
    var JObject=Java.type(“Java.lang.Object”);
    //返回Java.extend(JObject,this);//不起作用
    //返回此;//不起作用
    //返回新的JavaAdapter(java.lang.Object,this);//使用load(“nashorn:mozilla_compat.js”);
    var Type=Java.extend.apply(Java[JObject]);
    返回新类型(此);
    }
    var hm=新的HashMap();
    hm.put(新顶点1(1,10),10);
    hm.put(新顶点1(1,20),21);
    //照片尺寸是2号,但我想看1号
    打印(“哈希映射大小:+hm.size());
    //打印错误
    打印(“HashMap包含:”+hm.containsKey(新的顶点1(1,20)));
    
    编辑2

    感谢Tomasz,正如他所指出的,每次使用特定于类的实现对象调用Java.extend()函数都会生成一个新的Java适配器类
    var vertex = new JavaAdapter(java.lang.Object, new Vertex(1, 10));
    hm.put(vertex, 10);
    
    load("nashorn:mozilla_compat.js");
    
    // we will need a factory method
    var createVertex = (function() { // i hope you are familiar with "inline" function calls
    
        // private variables used in every call of factory method - but initialized once
        var 
            JObjExtender = Java.extend(Java.type("java.lang.Object")),
            JInteger = Java.type("java.lang.Integer"),
            _equals = function(other) { 
                return this.from === other.from; 
            },
            _hashCode = function() { 
                return JInteger.hashCode(+this.from); // leading "+" converts to number
            };
    
        // the "actual" factory method
        return function(from, cost) {
            return new JObjExtender() {
                from : from,
                cost : cost, 
                equals : _equals,
                hashCode : _hashCode
            };
        };
    })();
    
    var vertex = createVertex(1, 10);
    hm.put(vertex, 10);
    
    var v1 = createVertex(1, 10);
    var v2 = createVertex(1, 20);
    
    var classEquals = (v1.class === v2.class); // produces : true
    
    var v1 = new java.lang.Object(new JSVertex(10, 10));
    // produces: TypeError: Can not construct java.lang.Object with the passed
    // arguments; they do not match any of its constructor signatures.
    
    var JSVertex = function (from, cost) {
        this.from = from;
        this.cost = cost;
    };
    JSVertex.prototype = {
        equals : function(other) { 
            return this.from === other.from; 
        },
        hashCode : function() { 
            return java.lang.Integer.hashCode(+this.from); // leading "+" converts to number
        },
        compare : function(other) {
            return this.from - (+other.from);
        }
    };
    
    var v1 = new java.lang.Comparable(new JSVertex(10, 10));
    print(v1.class); 
    // produces both: class jdk.nashorn.javaadapters.java.lang.Object and
    // class jdk.nashorn.javaadapters.java.lang.Comparable
    
    var v2 = new java.lang.Comparable(new JSVertex(11, 12));
    print(v2 instanceof java.lang.Object); // produces true
    print(v2 instanceof java.lang.Comparable); // produces true
    
    var JSVertex = function (from, cost) {
        this.from = +from;
        this.cost = +cost;
    };
    JSVertex.prototype = {
        equals : function(other) { 
            print("[JSVertex.prototype.equals " + this + "]");
            return this.from === other.from;
        },
        hashCode : function() { 
            var hash = java.lang.Integer.hashCode(this.from);
            print("[JSVertex.prototype.hashCode " + this + " : " + hash + "]");
            return hash;
        },
        toString : function() {
            return "[object JSVertex(from: " + 
                this.from + ", cost: " + this.cost + ")]";
        },
        // this is a custom method not defined in any Java class or Interface
        calculate : function(to) { 
            return Math.abs(+to - this.from) * this.cost;
        }
    };
    
    var wrapJso = (function() { 
    
        var 
            JObjExtender = Java.extend(Java.type(
                "jdk.nashorn.api.scripting.AbstractJSObject")),
            _getMember = function(name) {
                return this.jso[name];
            },
            _setMember = function(name, value) {
                this.jso[name] = value;
            },
            _toString = function() { 
                return this.jso.toString();
            };
    
        return function(jsObject) {
            var F = function() {};
            F.prototype = jsObject;
            var f = new F();
            f.jso = jsObject;
            f.getMember = _getMember;
            f.setMember = _setMember;
            f.toString = _toString; // "toString hack" - explained later
            return new JObjExtender(f);
        };
    })();
    
    var wrapped = wrapJso(new JSVertex(11,12));
    
    // access custom js property and method not defined in any java class 
    // or interface.
    print(wrapped.from);
    print(wrapped.calculate(17));
    
    print("--------------");
    
    // call toString() and hashCode() from JavaScript on wrapper object
    print(wrapped.toString());
    print(wrapped.hashCode());
    
    print("--------------");
    
    // Use StringBuilder to make Java call toString() on our wrapper object.
    print(new java.lang.StringBuilder().append(wrapped).toString() );
    // see hack in wrapJso() - for some reason java does not see 
    // overriden toString if it is defined as prototype member.
    
    // Do some operations on HashMap to get hashCode() mehod called from java
    var map = new java.util.HashMap();
    map.put(wrapped, 10);
    map.get(wrapped);
    
    wrapped.from = 77;
    map.get(wrapped);
    
    print("--------------");
    
    // let's show that modyfing any of pair: wrapped or jso touches underlying jso.
    var jso = new JSVertex(17,128);
    wrapped = wrapJso(jso);
    print(wrapped);
    jso.from = 9;
    wrapped.cost = 10;
    print(wrapped);
    print(jso);
    print(jso == wrapped);
    
    11
    72
    --------------
    [object JSVertex(from: 11, cost: 12)]
    [JSVertex.prototype.hashCode [object JSVertex(from: 11, cost: 12)] : 11]
    11
    --------------
    [object JSVertex(from: 11, cost: 12)]
    [JSVertex.prototype.hashCode [object JSVertex(from: 11, cost: 12)] : 11]
    [JSVertex.prototype.hashCode [object JSVertex(from: 11, cost: 12)] : 11]
    [JSVertex.prototype.hashCode [object JSVertex(from: 77, cost: 12)] : 77]
    --------------
    [object JSVertex(from: 17, cost: 128)]
    [object JSVertex(from: 9, cost: 10)]
    [object JSVertex(from: 9, cost: 10)]
    false