【问题标题】:Java ArrayList<GenericObject>.remove(GenericObject) returns false, but still decrements size of ArrayListJava ArrayList<GenericObject>.remove(GenericObject) 返回 false,但仍会减小 ArrayList 的大小
【发布时间】:2011-11-07 03:24:52
【问题描述】:

这里有一些上下文: 我正在处理一项任务,以折叠存储半边数据结构的网格中的边。这是直接相关的代码。

    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

【问题讨论】:

  • 那是相当多的代码。我知道你很着急。如果您能提供SSCCE,这将有助于我们更快地回答您的问题。
  • 就在顶部。我之前很着急,这不是一段时间。
  • 不想给你带来困难,但这不是 100% 独立的。

标签: java data-structures arraylist mesh


【解决方案1】:

一个很简单的问题,但被你所有的代码弄得一团糟:

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

它是 if 条件末尾的分号。该分号结束了语句,这是您的 if 语句。它会将 if 块的“then”部分变成一个空语句(所以 nothing 会发生)。然后你有一个浮动块,总是发生。

您的代码执行如下:

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;您只是未能正确报告结果。删除分号,输出应该开始对您有意义。

【讨论】:

  • 想它会是这样的。谢谢。
【解决方案2】:

您使用的是哪个 JVM? Sun 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 类中包含这一行吗?

【讨论】:

  • List faces = new ArrayList();
  • @user1032935 好吧,这排除了非最终类的可能性。您使用的是哪个 JVM?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 2020-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多