0

So, this is my class:

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;
    }
}

I'm sorry, it's much to read, what I'm trying to do is: a Segment has an ID and an ArrayList of NodeIDs. I collect all the NodeIDs until one doesnt pass the getAngle- check, then go to the next segment.

Where I Log.d with the ONE tag, all the NodeIDs are in the segment. Where I Log.d with the TWO tag, the ArrayList of NodeIDs is empty. When I return the segments- ArrayList, the segments in it are there (havin an ID), but the NodeID- ArrayLists of all the segments are empty. Where am I losing the content? I'm going crazy over this.

Brendan Long
  • 53,280
  • 21
  • 146
  • 188
fweigl
  • 21,278
  • 20
  • 114
  • 205
  • I removed BOTH segmentNodes.clear(), now it isnt working as I expected but at least theres some content in those ArrayLists. It's totally new to me that this also clears the ArrayLists that I have already "stored away". Thanks a bunch! – fweigl Sep 14 '12 at 20:36

1 Answers1

1

Your issue stems from a misunderstanding of how Java handles Objects and references.

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);

Let's take a look at what Java is going to your objects as you "store" them. In the first chunk, you added a "trip" to segmentNodes. Then you added a reference to segmentNodes to the newly created Segment object. Because you added a reference, all changes made to segmentNodes will also be seen within the Segment's reference of segmentNodes.

Then you printed some data out, but you aren't altering anything so nothing should change.

Then, you call segmentNodes.clear(). This cleared out all the data in segmentNodes, but since you gave a reference of segmentNodes to the segment instance, it lost all the integers, too. Now, if you want the segment object to have its own copy of the segmentNodes list so that changes to the segmentNodes list does not affect the list in the Segment instance.

To do that, manually create a copy:

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

Java does not pass copies of Objects, it passes a copy of the reference. You may find this Stackoverflow Question about this topic helpful.

Community
  • 1
  • 1
kurtzbot
  • 512
  • 6
  • 19
  • Thank you very much for the explanation. Its kinda strange that in over a year of java programming i've never come across this. – fweigl Sep 14 '12 at 22:40