【问题标题】:port java lambda predicate to scala将 java lambda 谓词移植到 scala
【发布时间】:2019-08-14 22:22:26
【问题描述】:

如何移植https://github.com/davidmoten/rtree2/blob/master/src/test/java/com/github/davidmoten/rtree2/LatLongExampleTest.java#L55

Iterables.filter(tree
                // do the first search using the bounds
                .search(bounds),
                // refine using the exact distance
                entry -> {
                    Point p = entry.geometry();
                    Position position = Position.create(p.y(), p.x());
                    return from.getDistanceToKm(position) < distanceKm;
                });

从 Java 到 Scala?我下面的方法失败了:

import com.github.davidmoten.grumpy.core.Position
import com.github.davidmoten.rtree2.{Iterables, RTree}
import com.github.davidmoten.rtree2.geometry.{Geometries, Point}

val sydney = Geometries.point(151.2094, -33.86)
val canberra = Geometries.point(149.1244, -35.3075)
val brisbane = Geometries.point(153.0278, -27.4679)
val bungendore = Geometries.point(149.4500, -35.2500)

var tree = RTree.star.create[String, Point]
tree = tree.add("Sydney", sydney)
tree = tree.add("Brisbane", brisbane)

val distanceKm = 300
val list = Iterables.toList(search(tree, canberra, distanceKm))

def createBounds(from: Position, distanceKm: Double) = { // this calculates a pretty accurate bounding box. Depending on the
  // performance you require you wouldn't have to be this accurate because
  // accuracy is enforced later
  val north = from.predict(distanceKm, 0)
  val south = from.predict(distanceKm, 180)
  val east = from.predict(distanceKm, 90)
  val west = from.predict(distanceKm, 270)
  Geometries.rectangle(west.getLon, south.getLat, east.getLon, north.getLat)
}

import com.github.davidmoten.grumpy.core.Position
import com.github.davidmoten.rtree2.RTree

def search[T](tree: RTree[String, Point], lonLat: Point, distanceKm: Double) = { // First we need to calculate an enclosing lat long rectangle for this
  // distance then we refine on the exact distance
  val from = Position.create(lonLat.y, lonLat.x)
  val bounds = createBounds(from, distanceKm)
  Iterables.filter(tree.search // do the first search using the bounds
  (bounds), // refine using the exact distance
    (entry) => {
      def foo(entry) = {
        val p = entry.geometry
        val position = Position.create(p.y, p.x)
        from.getDistanceToKm(position) < distanceKm
      }

      foo(entry)
    })
}

因为entry 的类型似乎没有很好的定义。

【问题讨论】:

  • 这意味着:(entry:Predicate[Entry[String, Point]]) =&gt; { def foo(entry:Predicate[Entry[String, Point]]) = { val p = entry.geometry val position = Position.create(p.y, p.x) from.getDistanceToKm(position) &lt; distanceKm }。但是,这仍然不起作用。
  • 查看获得最多赞的第二个答案。这取决于你的 scala 版本
  • 有趣。但是,import scala.compat.java8.FunctionConverters._ Iterables.filter(tree.search // do the first search using the bounds (bounds), // refine using the exact distance ((entry: Predicate[Entry[String, Point]]) =&gt; { val p = entry.geometry val position = Position.create(p.y, p.x) from.getDistanceToKm(position) &lt; distanceKm }).asJava ) 仍然无法编译。

标签: java scala lambda predicate scala-java-interop


【解决方案1】:

tree 的类型为 RTree[String, Point],所以 T=StringS=Point。所以tree.search(bounds) 的类型为Iterable[Entry[String, Point]]。所以entry 的类型为Entry[String, Point]

试试

(entry: Entry[String,Point]) => {
  def foo(entry: Entry[String,Point]) = {
    val p = entry.geometry
    val position = Position.create(p.y, p.x)
    from.getDistanceToKm(position) < distanceKm
  }

  foo(entry)
})

在 Scala 2.13.0、rtree2 0.9-RC1、grumpy-core 0.2.4 中测试。


在 2.11 中应该只是

import scala.compat.java8.FunctionConverters._

((entry: Entry[String,Point]) => {
  def foo(entry: Entry[String,Point]) = {
    val p = entry.geometry
    val position = Position.create(p.y, p.x)
    from.getDistanceToKm(position) < distanceKm
  }

  foo(entry)
}).asJava

libraryDependencies += "org.scala-lang.modules" %% "scala-java8-compat" % "0.9.0"

【讨论】:

  • 你也有支持 scala 2.11 的东西吗?这将是我工作所必需的,因为 spark 仍然主要使用这个旧版本。
  • @GeorgHeiler 已更新。
  • 我还没有运行它,但是编译器很高兴。伟大的。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多