0

所以,这是我的课:

public class SegmentMaker {

    public ArrayList<Segment> makeSegments(CustomNodes cn, Trip myTrip) {

        ArrayList<Segment> segments = new ArrayList<Segment>();
        ArrayList<Integer>segmentNodes = new ArrayList<Integer>();

        int count = 0; 

        for (int i=0; i < myTrip.getTripList().size(); i++){
            Log.d(TAG, "checking " + cn.getOsmID(myTrip.getTripItem(i)));

            if (i==0) {
                segmentNodes.add(myTrip.getTripItem(i));     
            }

            else if (i==myTrip.getTripList().size()-2) {
                segmentNodes.add(myTrip.getTripItem(i));     
            }

            else if (i==myTrip.getTripList().size()-1) {
                segmentNodes.add(myTrip.getTripItem(i)); 
                Segment segment = new Segment();
                segment.setId(count); 
                segment.setNodeIds(segmentNodes); 

                Log.d(TAG, "in SM segment " + segment.getId() + " nodes: " + segment.getNodeIds().toString());
                segmentNodes.clear(); 
                count++; 
                segments.add(segment);
                Log.d(TAG, "in SM segment " + segment.getId() + " nodes: " );
                for (int x=0; x<segment.getNodeIds().size(); x++) {
                    Log.d(TAG, "   " + segment.getNodeIds().get(x));
                }
                break; 
            }

            else if ((getAngle(myTrip.getTripItem(i), myTrip.getTripItem(i+1), myTrip.getTripItem(i+2),cn) < 25)  &&  
                    (getAngle(myTrip.getTripItem(i), myTrip.getTripItem(i+1), myTrip.getTripItem(i+2),cn) > -25))  
            {
                segmentNodes.add(myTrip.getTripItem(i));         
            }

            else {
                segmentNodes.add(myTrip.getTripItem(i)); 
                Segment segment = new Segment();
                segment.setId(count); 
                segment.setNodeIds(segmentNodes); 

                Log.d(ONE, "in SM segment " + segment.getId() + " nodes: " + segment.getNodeIds().toString());

                segments.add(segment);
                segmentNodes.clear(); 
                count++; 
            }
        }

        Log.d(TWO, " segments SM ende: " + segments.get(0).getNodeIds().size());
        return segments; 
    }

    public float getAngle(int firstItem, int secondItem, int thirdItem, CustomNodes cn){
        //do some stuff

        return angle;
    }
}

很抱歉,要阅读的内容很多,我想做的是:一个 Segment 有一个 ID 和一个 NodeID 的 ArrayList。我收集所有的 NodeID,直到一个没有通过 getAngle-检查,然后转到下一个段。

在我使用 ONE 标记进行 Log.d 的地方,所有 NodeID 都在该段中。在我用 TWO 标记 Log.d 的地方,NodeID 的 ArrayList 是空的。当我返回segments-ArrayList 时,其中的segment 在那里(有一个ID),但所有segment 的NodeID-ArrayLists 都是空的。我在哪里丢失了内容?我要疯了。

4

1 回答 1

1

您的问题源于对 Java 如何处理对象和引用的误解。

segmentNodes.add(myTrip.getTripItem(i)); 
Segment segment = new Segment();
segment.setId(count); 
segment.setNodeIds(segmentNodes); 

Log.d(TAG, "in SM segment " + segment.getId() + " nodes: " 
    + segment.getNodeIds().toString());
segmentNodes.clear(); 
count++; 
segments.add(segment);

让我们看一下当您“存储”对象时,Java 将如何处理您的对象。在第一个块中,您向segmentNodes. 然后,您添加了对新创建的 Segment 对象的引用。segmentNodes因为您添加了引用,所以对 的所有更改segmentNodes也将在Segment的引用中看到segmentNodes

然后你打印了一些数据,但你没有改变任何东西,所以什么都不应该改变。

然后,您调用segmentNodes.clear(). 这清除了 中的所有数据segmentNodes,但是由于您提供了对segmentNodes实例segment的引用,因此它也丢失了所有整数。现在,如果您希望segment对象拥有自己的列表副本segmentNodes,以便对列表的更改segmentNodes不会影响 Segment 实例中的列表。

为此,请手动创建一个副本:

ArrayList<Integer> segCopy = new ArrayList<Integer>();
for(Integer i : segmentNodes){
    segCopy.add(i);
}
segment.setNodeIds(segCopy);
segmentNodes.clear();

Java 不传递对象的副本,它传递引用的副本。您可能会发现有关此主题的Stackoverflow 问题很有帮助。

于 2012-09-14T21:06:26.497 回答