2011-11-07 31 views
2

以下是一些上下文: 我正在處理摺疊存儲半邊數據結構的網格中的邊的分配。這是直接相關的代碼。Java ArrayList <GenericObject> .remove(GenericObject)返回false,但仍然遞減ArrayList的大小

System.out.println("Initial Size: " +heds.faces.size()); 
    if (! heds.faces.remove(currentHE.twin.leftFace)); 
    { 
     System.out.println("We have a twin problem"); 
      //this will always print 
    } 
    // Yet this will always be 1 less than the initial 
    System.out.println("After twin removal: " +heds.faces.size()); 

    if (!heds.faces.remove(currentHE.leftFace)) 
    { 
     System.out.println("We have a problem"); 
    } 
    System.out.println("Third: " +heds.faces.size()); 

所以問題是,「我們有一個雙胞胎的問題」總是版畫,它不應該,但是,「雙後去除」永遠是比初始尺寸小一。

如果你覺得你需要它,下面是其餘的信息。 HEDS在類定義的「HEDS」(半邊緣數據結構):

 public HEDS(PolygonSoup soup) { 
    HalfEdge potentialTwin; 
    HalfEdge[] currHalfEdges; 
    Vertex curr, next;  
    for (int[] face : soup.faceList) 
    { 
     currHalfEdges = new HalfEdge[face.length]; 
     for (int i = 0; i < face.length; i++) 
     { 
      HalfEdge he = new HalfEdge(); 

      curr = soup.vertexList.get(face[i]); 
      next = soup.vertexList.get(face[(i+1)%face.length]); 

      he.tail = curr; 
      he.head = next; 
      currHalfEdges[i] = he; 
      halfEdges.put(face[i]+","+face[(i+1)%face.length], he); 

      potentialTwin = halfEdges.get(face[(i+1)%face.length]+","+face[i]); 

      if (potentialTwin != null) 
      { 
       he.twin = potentialTwin; 
       potentialTwin.twin = he; 
      }  
     } 
     for (int i = 0; i < currHalfEdges.length; i++) 
     { 

      currHalfEdges[i].next = currHalfEdges[(i+1)%currHalfEdges.length]; 
     } 

     faces.add(new Face(currHalfEdges[0])); 
    } 

    // Checking if every half-edge's face was propery defined 
    Iterator<Entry<String, HalfEdge>> it = halfEdges.entrySet().iterator(); 
    while (it.hasNext()) 
    { 
     Map.Entry<String, HalfEdge> pairs = (Map.Entry<String, HalfEdge>)it.next(); 
     if (!faces.contains(pairs.getValue().twin.leftFace)) 
     { 
      System.out.println("DAMN IT!!!!!"); 
        // This is never reached 
     } 

    } 

此外,它似乎並不重要,如果我第一或不除去雙子的臉。此外,可以假定網格在此處是多方面的。

半邊:

public class HalfEdge { 

public HalfEdge twin; 
public HalfEdge next; 
public Vertex head; 
public Vertex tail; 
public Face leftFace; 

/** 
* while perhaps wasting space, it may be convenient to 
* have a common edge object for each pair of half edges to 
* store information about the error metric, optimal vertex 
* location on collapse, and the error 
*/ 
public Edge e; 

/** @return the previous half edge (could just be stored) */ 
public HalfEdge prev() { 
    HalfEdge prev = this; 
    while (prev.next != this) prev = prev.next;   
    return prev; 
} 
/** 
* Computes the valence by walking around the vertex at head. 
* @return valence of the vertex at the head of this half edge 
*/ 
public int valence() { 
    HalfEdge loop = this; 
    int v = 0; 
    do { 
     v++; 
     loop = loop.next.twin; 
    } while (loop != this); 
    return v; 
} 

臉代碼:

public class Face {  
/** sure, why not keep a normal for flat shading? */ 
public Vector3d n = new Vector3d(); 

/** Plane equation */ 
Vector4d p = new Vector4d(); 

/** Quadratic function for the plane equation */ 
public Matrix4d K = new Matrix4d(); 

/** Some half edge on the face */ 
HalfEdge he; 

/** 
* Constructs a face from a half edge, and computes the flat normal 
* @param he 
*/ 
public Face(HalfEdge he) { 
    this.he = he; 
    HalfEdge loop = he; 
    do { 
     loop.leftFace = this; 
     loop = loop.next; 
    } while (loop != he); 
    recomputeNormal(); 
} 

public Face(List<Vertex> vertexList, int[] faceVertices) 
{ 

} 

public void recomputeNormal() { 
    Point3d p0 = he.head.p; 
    Point3d p1 = he.next.head.p; 
    Point3d p2 = he.next.next.head.p; 
    Vector3d v1 = new Vector3d(); 
    Vector3d v2 = new Vector3d(); 
    v1.sub(p1,p0); 
    v2.sub(p2,p1); 
    n.cross(v1,v2); 

    // TODO: compute the plane and matrix K for the quadric error metric 

} 

}

很抱歉的最後一個問題,我是有點倉促,並希望能有一個解決方案簡單https://stackoverflow.com/questions/8031446/java-arraylist-removeo-returns-false-but-still-decrements-size-of-arraylist

+2

這是相當多的代碼。我知道你很匆忙。如果您可以提供[SSCCE](http://sscce.org),它將幫助我們更快地回答您的問題。 –

+0

它是在頂部。我以前很匆忙,這不是一段時間。 – julianc

+0

沒有試圖給你一個困難的時間,但這不是100%自包含。 –

回答

7

一個非常簡單的問題,但所有的代碼蒙上陰影:

if (! heds.faces.remove(currentHE.twin.leftFace)); 
{ 
    //... 
} 

這是在IF條件的最後的分號。該分號結束語句,這是您的if語句。它將你的if塊的「then」部分變成空的語句(所以沒有發生)。然後你有一個浮動塊,總是發生。

你的代碼執行是這樣的:

if (! heds.faces.remove(currentHE.twin.leftFace)) 
    ; //this empty statement never gets executed, but nothing to execute anyhow 


{ 
    //this will always print (since it's not guarded by the if) 
    System.out.println("We have a twin problem"); 
} 

換句話說,heds.faces.remove()確實返回true;你只是沒有正確地報告結果。刪除分號,輸出應該開始對你有意義。

+0

想象它會是這樣的。謝謝。 – julianc

1

您正在使用哪種JVM?太陽JDK(即也OpenJDK的)具有以下實現:

public boolean remove(Object o) { 
if (o == null) { 
     for (int index = 0; index < size; index++) 
    if (elementData[index] == null) { 
     fastRemove(index); 
     return true; 
    } 
} else { 
    for (int index = 0; index < size; index++) 
    if (o.equals(elementData[index])) { 
     fastRemove(index); 
     return true; 
    } 
    } 
return false; 
} 

注意,return false情況下只能通過o底層陣列中沒有被發現引起。

另請注意,ArrayList不是最終的類 - 它可以通過做出錯誤的事情來擴展。

最後,你的代碼沒有顯示你的ArrayList的聲明 - 你可以在你的HEDS類中包含這一行嗎?

+0

List faces = new ArrayList (); – julianc

+0

@ user1032935那麼,這就排除了非最終類的可能性。你使用哪種JVM? – Bringer128