Java ArrayList.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
}
}
此外,我是否先删除双胞胎的脸似乎并不重要。还可以假设此时网格是流形的。
Half Edge:
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;
}
Face code:
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
Here's some context:
I'm working on an assignment to collapse an edge in a mesh that is stored half-edge data structure. This is the immediately relevant code.
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());
So the problem is that "We have a twin problem" always prints, and it should not, yet, "After twin removal" will always be one less than the initial size.
Here's the rest of the info if you feel you need it.
heds is defined in a class "HEDS" (half edge data structure):
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
}
}
Also it does not seem to matter if I remove the twin's face first or not. Also it can be assumed that the mesh is manifold at this point.
Half Edge:
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;
}
Face code:
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
}
}
Sorry about the last question, I was in a bit of a rush, and was hoping there was a simple solution. https://stackoverflow.com/questions/8031446/java-arraylist-removeo-returns-false-but-still-decrements-size-of-arraylist
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个非常简单的问题,但被所有代码所掩盖:
它是 if 条件末尾的分号。该分号结束该语句,即您的 if 语句。它将 if 块的“then”部分变成一个空语句(所以什么也不会发生)。然后你会在它之后有一个浮动块,总是发生。
您的代码执行如下:
换句话说,
heds.faces.remove()
确实返回 true;您只是未能正确报告结果。删除分号,输出应该开始对您有意义。Quite a simple problem, but clouded by all your code:
It's the semicolon at the end of the if-condition. That semicolon ends the statement, which is your if statement. It turns the "then" part of your if block into an empty statement (so nothing happens). Then you have a floating block after it that always happens.
Your code executes like this:
In other words,
heds.faces.remove()
is indeed returning true; you just failed to report the result correctly. Remove the semi-colon and the output should start to make sense to you.您使用哪个 JVM? Sun JDK(即 OpenJDK)具有以下实现:
请注意,
return false
情况只能由在底层数组中找不到o
引起。另请注意,
ArrayList
不是最终类 - 它可能会通过执行错误操作的内容进行扩展。最后,您的代码没有显示 ArrayList 的声明 - 您可以在 HEDS 类中包含这一行吗?
Which JVM are you using? The Sun JDK (i.e. also OpenJDK) has the following implementation:
Note that the
return false
case can only be caused byo
not being found in the underlying array.Also note that
ArrayList
is not a final class - it could be extended by something that is doing the wrong thing.Finally, your code does not show the declaration of your
ArrayList
- can you include this line from your HEDS class?