Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.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
Java 通过scala处理深度优先迭代时的StackOverflower错误_Java_Scala_Recursion_Stack Overflow - Fatal编程技术网

Java 通过scala处理深度优先迭代时的StackOverflower错误

Java 通过scala处理深度优先迭代时的StackOverflower错误,java,scala,recursion,stack-overflow,Java,Scala,Recursion,Stack Overflow,我打算递归迭代圆形区域内的所有网格,下面的代码将执行深度优先搜索。但在204个堆栈之后,将抛出java.lang.StackOverflowerError def geohash_circle_around_point(lat: Double, lon: Double, radius: Double) = { def expand_neighbors_impl(ghCenter: GeoHash, ghCur: GeoHash, buffer: collection.mutable.Set

我打算递归迭代圆形区域内的所有网格,下面的代码将执行深度优先搜索。但在204个堆栈之后,将抛出
java.lang.StackOverflowerError

def geohash_circle_around_point(lat: Double, lon: Double, radius: Double) = {

  def expand_neighbors_impl(ghCenter: GeoHash, ghCur: GeoHash, buffer: collection.mutable.Set[GeoHash]): Unit = {
    // MARK: DP: check whether it's iterated already or not
    if(buffer contains ghCur)  {
      return
    }
    buffer += ghCur

    for(ghAround <- get4GeoHashAround(ghCur))  {
      if(distanceBetweenGeohash(ghCenter, ghAround) <= radius)  {
        expand_neighbors_impl(ghCenter, ghAround, buffer)
      }
    }
  }

  def get4GeoHashAround(gh: GeoHash): Array[GeoHash] = {
    Array(gh.getNorthernNeighbour, gh.getSouthernNeighbour, gh.getWesternNeighbour, gh.getEasternNeighbour)
  }

  def distanceBetweenGeohash(gh1: GeoHash, gh2: GeoHash) = {
    haversine(gh1.getBoundingBoxCenterPoint.getLatitude, gh1.getBoundingBoxCenterPoint.getLongitude, gh2.getBoundingBoxCenterPoint.getLatitude, gh2.getBoundingBoxCenterPoint.getLongitude)
  }

  val ghCenter = GeoHash.withBitPrecision(lat, lon, 40)
  val s = collection.mutable.Set[GeoHash]()
  expand_neighbors_impl(ghCenter, ghCenter, s)
  s.map(_.getBoundingBox)
}
谁能给点建议吗?谢谢

p.S.

实现
等于
hashCode
GeoHash

public boolean equals(Object obj) {
    if(obj == this) {
        return true;
    } else {
        if(obj instanceof GeoHash) {
            GeoHash other = (GeoHash)obj;
            if(other.significantBits == this.significantBits && other.bits == this.bits) {
                return true;
            }
        }

        return false;
    }
}

public int hashCode() {
    byte f = 17;
    int f1 = 31 * f + (int)(this.bits ^ this.bits >>> 32);
    f1 = 31 * f1 + this.significantBits;
    return f1;
}

看起来你真的需要200多个呼叫,精确到
40

你可能想考虑将你的递归改写为尾递归,以便编译器优化。以下是一种方法:

@tailrec
def expand_neighbors_impl(ghCenter: GeoHash, toGoThrough: List[GeoHash], buffer: Set[GeoHash] = Set()): Set[GeoHash] = {
  toGoThrough.headOption match {
    case None => buffer
    case Some(ghCur) =>
      if (buffer contains ghCur) {
        expand_neighbors_impl(ghCenter, toGoThrough.tail, buffer)
      }
      else {
        val neighbors = get4GeoHashAround(ghCur).filter(distanceBetweenGeohash(ghCenter, _) <= radius)
        expand_neighbors_impl(ghCenter, neighbors ++: toGoThrough, buffer + ghCur)
      }
  }
}

def expand_neighbors_impl(ghCenter: GeoHash, ghCur: GeoHash): Set[GeoHash] =
  expand_neighbors_impl(ghCenter, List(ghCur))
@tailrec
def expand_neights_impl(ghCenter:GeoHash,toGoThrough:List[GeoHash],buffer:Set[GeoHash]=Set()):Set[GeoHash]={
toGoThrough.headOption匹配{
case None=>buffer
案例部分(ghCur)=>
if(缓冲区包含ghCur){
展开\u邻居\u impl(ghCenter、toGoThrough.tail、buffer)
}
否则{

val Neights=get4GeoHashAround(ghCur).filter(ghCenter和H之间的距离)我相信
contains
总是返回false,因为
Geohash
没有
equals
方法?如果是这种情况,那么它将继续添加相同的对象。@DarshanMehta,对于
HashSet
,方法
hashCode
也是必需的。@CyrilleCorpet不言而喻..Java最初提供了一个小堆栈用于重新编译所以当你调用超过100000个递归函数(DFS调用)时,你可能会遇到StackOverFlow异常。你可以用两种方法来解决它。1)您可以实现自己的堆栈,该堆栈将用作递归堆栈。2)您可以创建一个线程,并根据您的最大需求分配内存。GeoHash已实现@DarshanMehta
@tailrec
def expand_neighbors_impl(ghCenter: GeoHash, toGoThrough: List[GeoHash], buffer: Set[GeoHash] = Set()): Set[GeoHash] = {
  toGoThrough.headOption match {
    case None => buffer
    case Some(ghCur) =>
      if (buffer contains ghCur) {
        expand_neighbors_impl(ghCenter, toGoThrough.tail, buffer)
      }
      else {
        val neighbors = get4GeoHashAround(ghCur).filter(distanceBetweenGeohash(ghCenter, _) <= radius)
        expand_neighbors_impl(ghCenter, neighbors ++: toGoThrough, buffer + ghCur)
      }
  }
}

def expand_neighbors_impl(ghCenter: GeoHash, ghCur: GeoHash): Set[GeoHash] =
  expand_neighbors_impl(ghCenter, List(ghCur))