0

I want to do the following:

I have a List with Objects, which contain a Date, now I want to use this objects not only for one Date, I want to set the date and reuse them. Selected List contains 5 elements.

while((stop.equals(countingDate)) || (countingDate.before(stop))) {
           
           for (c_TakeTimeObjects c_takeTimeObjects : SelectedList) {
               c_TakeTimeObjects addingObj = new c_TakeTimeObjects(1,1,"",true,this);
               
               c_takeTimeObjects.setsActivityDate(c_HelperClass_CalToStringDate.get(countingDate, 0, 0, 0));
               addingObj = c_takeTimeObjects;
               Log.i(TAG, "adjustDateRange: "+ addingObj.getsActivityDate());
               editList.add(addingObj);
           }
           countingDate.add(Calendar.DAY_OF_MONTH, +1);
       }

as you probably guess, the Log shows different dates caused by the loop, but the final list only has elements with the same Date.

log.i gives me:

    adjustDateRange: 25.06.2019
    adjustDateRange: 25.06.2019
    adjustDateRange: 25.06.2019
    adjustDateRange: 25.06.2019
    adjustDateRange: 25.06.2019
    adjustDateRange: 26.06.2019
    adjustDateRange: 26.06.2019
    adjustDateRange: 26.06.2019
    adjustDateRange: 26.06.2019
    adjustDateRange: 26.06.2019
    adjustDateRange: 27.06.2019
    adjustDateRange: 27.06.2019
    adjustDateRange: 27.06.2019
    adjustDateRange: 27.06.2019
    adjustDateRange: 27.06.2019
    adjustDateRange: 28.06.2019
    adjustDateRange: 28.06.2019
    adjustDateRange: 28.06.2019
    adjustDateRange: 28.06.2019
    adjustDateRange: 28.06.2019

and iterating through the List, after all objects are added gives me:

for(c_TakeTimeObjects c_takeTimeObjects: editList){
            Log.i(TAG, "EditList: " + c_takeTimeObjects.getsActivityDate());
        }

    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019
    EditList: 28.06.2019

This is, because there is a reference between the objects I add, how can I avoid this? Maybe one solution is a DeepCopy, but is this really necessary?

Update

This Code produces the same result:

while((stop.equals(countingDate)) || (countingDate.before(stop))) {
           for (c_TakeTimeObjects c_takeTimeObjects : SelectedList) {
                c_takeTimeObjects.setsActivityDate(c_HelperClass_CalToStringDate.get(countingDate,0,0,0));
                Log.i(TAG, "adjustDateRange: "+ c_takeTimeObjects.getsActivityDate());
                editList.add(c_takeTimeObjects);
               
           }
           countingDate.add(Calendar.DAY_OF_MONTH, +1);
       }
Community
  • 1
  • 1
  • 1
    Are you sure `SelectedList` contains different objects not just multiple references to a single object? And please, write your code having Java Code Guidelines in mind. – jsamol Jul 22 '19 at 14:51
  • SelectedList contains Objects of the calss `c_TakeTimeObjects` and they all have different values assigned. Like start and stop time or status. In my example SelectedList has 5 objects. – HydroHeiperGen Jul 22 '19 at 14:59
  • I added the complete Log.i. with SelectedList having 5 elements – HydroHeiperGen Jul 22 '19 at 15:06

3 Answers3

0

Try moving this line c_TakeTimeObjects addingObj = new c_TakeTimeObjects(1,1,"",true,this); into for before addingObj = c_takeTimeObjects;

Edit:

I dont understand your code. But can you try editList.add(c_takeTimeObjects); instead of editList.add(addingObj);

faranjit
  • 1,567
  • 1
  • 15
  • 22
  • Sorry, this was what I wanted to post at first. – HydroHeiperGen Jul 22 '19 at 14:30
  • You may asked yourself why I made the Object addingObj, because I could use c_takeTimeObject directly. But I made this, because I thought it may helps breaking the reference between those two objects. – HydroHeiperGen Jul 22 '19 at 14:46
  • Yeah, you are right. I wonder what is the result of `c_HelperClass_CalToStringDate.get(countingDate,0,0,0)`? – faranjit Jul 22 '19 at 14:53
  • I made this Helper, to get a String Date (Format dd.MM.yy) out of a Calender value. The int values in the back are just days, months or years you want to add or substract from the Calendervalue you pass in the front. – HydroHeiperGen Jul 22 '19 at 14:55
  • Ok, let's do like this: `c_TakeTimeObjects addingObj = new c_TakeTimeObjects(1,1,"",true,this); addingObj.setsActivityDate(c_HelperClass_CalToStringDate.get(countingDate, 0, 0, 0)); ` – faranjit Jul 22 '19 at 15:18
0

Let me guess : your SelectedList contains only 1 item, right ?
Actually by doing

addingObj = c_takeTimeObjects;

you always replace your addingObj variable with c_takeTimeObjects so in the end, you have added 5 times the same instance (c_takeTimeObjects) to your editList (and you even modified the content of your SelectedList)
So either you create a new instance and copy the attributes you need manually

    for (c_TakeTimeObjects c_takeTimeObjects : SelectedList) {
        c_TakeTimeObjects addingObj = new c_TakeTimeObjects(1,1,"",true,this);
        addingObj.setsActivityDate(c_HelperClass_CalToStringDate.get(countingDate, 0, 0, 0));
// addingObj.setOtherAttribute1(c_takeTimeObjects.getOtherAttribute1);
// addingObj.setOtherAttribute2(c_takeTimeObjects.getOtherAttribute2);
        Log.i(TAG, "adjustDateRange: "+ addingObj.getsActivityDate());
        editList.add(addingObj);
    }

or you implement the Cloneable interface

    for (c_TakeTimeObjects c_takeTimeObjects : SelectedList) {
        c_TakeTimeObjects addingObj = (c_TakeTimeObjects) c_takeTimeObjects.clone();
        addingObj.setsActivityDate(c_HelperClass_CalToStringDate.get(countingDate, 0, 0, 0));
        Log.i(TAG, "adjustDateRange: "+ addingObj.getsActivityDate());
        editList.add(addingObj);
    }

EDIT Let's say that your 5 instances in SelectedList are A,B,C,D,E
1st iteration : with

c_TakeTimeObjects addingObj = new c_TakeTimeObjects(1,1,"",true,this);

addingObj is F. Then with

addingObj = c_takeTimeObjects

addingObj becomes A.
Then addingObj.setsActivityDate(...) sets 2019-06-25 to A and finally you add A to editList
2nd iteration : with

c_TakeTimeObjects addingObj = new c_TakeTimeObjects(1,1,"",true,this);

, addingObj is G. Then with

addingObj = c_takeTimeObjects

addingObj becomes B, Then addingObj.setsActivityDate(...) sets 2019-06-25 to B and finally you add B to editList
And so on until E. So the date for A, B, C, D, E is now set to 2019-06-25 and editList contains A,B,C,D,E. F,G,H,I,J have never been used
After this you start again with 2019-06-26 -> the date for A, B, C, D, E is now set to 2019-06-26 and editList contains A,B,C,D,E,A,B,C,D,E
Then you end with 2019-06-28 set to A,B,C,D,E and editList that contains A,B,C,D,E,A,B,C,D,E,A,B,C,D,E,A,B,C,D,E. All the other instances you have created with new are never used and lost.

Olivier Depriester
  • 1,615
  • 1
  • 7
  • 20
  • `SelectedList`has 5 items in my example. – HydroHeiperGen Jul 22 '19 at 14:54
  • So I don't get how Log.i can display different dates : The day of month is increased outside from the for loop – Olivier Depriester Jul 22 '19 at 14:58
  • Increased field is not month, it is the day of the month. – faranjit Jul 22 '19 at 15:00
  • I already edited my comment but it does not change the fact that ```countingDate``` is never modified within the loop – Olivier Depriester Jul 22 '19 at 15:02
  • @oliver the Day of month should be assigned to all elements of the List and than increment. After this, it should be assigned to all elements of the list again and so on. – HydroHeiperGen Jul 22 '19 at 15:09
  • After having seen your updated logs, I confirm that my first answer is right : you have added 4 times the 5 instances of your SelectedList AND you have changed the date of these 5 instances to the latest date = 28.06.2019. Only by creating copies of these instances can solve your problem – Olivier Depriester Jul 22 '19 at 15:15
  • @Oliver how would you implement a Cloneable interface? – HydroHeiperGen Jul 22 '19 at 15:15
  • Just this ```public class c_TakeTimeObjects implements Cloneable``` in your class declaration may be enough. If not, you will have to override the clone() method of this interface. – Olivier Depriester Jul 22 '19 at 15:22
  • Actually there are also some cons about using Cloneable so pay attention to the context in which you use it : https://stackoverflow.com/questions/4081858/about-java-cloneable. The main point here is to keep sure you create and use a new instance whatever is the method you use – Olivier Depriester Jul 22 '19 at 15:29
  • @Oliver now please edit your answer and tell me why c_TakeTimeObjects addobj = new c_TakeTimeObject(1,1,"",true,this); addobj = c_takeTimeObject; is not working, but: addobj.setsActivityDate(c_takeTimeObject.getsActivityState()); Works. – HydroHeiperGen Jul 22 '19 at 15:45
0

If you're using an ArrayList, remember that even if you add the Objects to another ArrayList, both arrays will reference the same Object.

That means this process goes like:

For each iteration of the while loop you iterate the for loop, changing the attribute of the Objects. After that you add them to the new ArrayList. When you get to the next while iteration, the for loop changes again the values OF THE SAME OBJECTS, which you add again to the new ArrayList.

Try this workaround:

Generate a constructor in c_TakeTimeObjects where you can pass a whole c_TakeTimeObjects object, and then edit the code like

editList.add(new c_TakeTimeObjects(c_takeTimeObjects ));
RipperJugo
  • 85
  • 4