jruby添加了一个java库

时间:2012-04-06 16:35:18

标签: java ruby jruby

我正在尝试在Jruby文件中运行http://www.savarese.com/software/libssrckdtree-j/

我的代码看起来像这样:

require 'java'
require 'libssrckdtree-j-1.0.2.jar'

GenericPoint = Java::com.savarese.spatial.GenericPoint
KDTree = Java::com.savarese.spatial.KDTree
NearestNeighbors = Java::com.savarese.spatial.NearestNeighbors

tree = KDTree.new

def generate_points(tree, size)
  size.times do
    x = rand(100)
    y = rand(100)
    point = GenericPoint.new(x, y)
    tree.put(point, point.to_s)
  end
end

generate_points(tree, 20000)


nearest = NearestNeighbors.new()
point = [1,1]

nearest.get(tree, point, 1, false)

然而,当我运行此代码时,我得到了

NameError: no method 'get' for arguments (com.savarese.spatial.KDTree,org.jruby.RubyArray,org.jruby.RubyFixnum,org.jruby.RubyBoolean) on Java::ComSavareseSpatial::NearestNeighbors
  (root) at kdjava.rb:25

我没有得到,因为该库的文档说使用get,并且我使用了树上的KDtree并且它有效。

我想要做的是使用这个库在kd树中构造一系列lat lngs,然后查询另一组lat lngs以查看KD树中最近的邻居。

我对Ruby很好 - 但我很擅长Java。我正在使用Jruby来利用这些更快的库。

1 个答案:

答案 0 :(得分:2)

api documentation for NearestNeighbor#get()表示该方法采用KDTree,P,int,boolean类型的四个参数,它们都是Java类型。

您的错误消息表明您传入了KDTree,RubyArray,RubyFixnum,RubyBoolean。所以,KDTree看起来不错。我相信JRuby会自动将Fixnum和Boolean强制转换为适当的Java类型。这使得第二个arg传递给RubyArray,方法需要P。

NearestNeighbors的文档表明P是泛型类型P extends Point<Coord>Point是一个界面。 GenericPoint实现了该接口。因此,不要传递[1,1],而是尝试传递Java::com.savarese.spatial.GenericPoint.new(1,1)

编辑:

进一步了解,GenericPoint必须使用Coord创建,Coord extends java.lang.Comparable<? super Coord>是另一种通用类型int。在Java中,有两种类型,基本类型java.lang.Integer(快速)和“盒装”对象IntegerComparable实现了GenericPoint接口,require 'java' require 'libssrckdtree-j-1.0.2.jar' GenericPoint = Java::com.savarese.spatial.GenericPoint KDTree = Java::com.savarese.spatial.KDTree NearestNeighbors = Java::com.savarese.spatial.NearestNeighbors def box(i) java.lang.Integer.new(i) end tree = KDTree.new def generate_points(tree, size) size.times do x = box(rand(100)) y = box(rand(100)) point = GenericPoint.new(x, y) tree.put(point, point.to_s) end end generate_points(tree, 20000) nearest = NearestNeighbors.new() point = GenericPoint.new(box(1), box(1)) nearest.get(tree, point, 1, false) 需要该接口。运行以下内容时没有出现任何错误:

Integer

关于上述内容的说明,通常在Java中创建一个盒装int,其中一个使用java.lang.Integer.valueOf(int)。出于我之外的原因,这导致了使用NativeException: java.lang.ClassCastException: org.jruby.RubyFixnum cannot be cast to java.lang.Numberjava.lang.Integer.new时出现的相同错误。所以我改为使用构造函数{{1}}。