简体   繁体   中英

Issue with Calendar within a while loop

I'm developing this time container which basically contains instances of a class called week, which is made of 2 Calendar instances (start and end) and a lot of other Administrative information's (for now not relevant)

The problem is that i create these Week instances in a while loop, and i see that during the creation of the week instances (printing the calendars milliseconds in the while loop), the millis are fine, but if i check the content of the list of weeks, they are not! all the instances of Calendar (start and end) contain the same values for all weeks.

I have wrote a bit of code to let you guys understand the problem clearly, there are the classes (Container and BiggerContainer):

public class Container
{
  private static final long serialVersionUID = 1L;

  private Calendar          start;

  private Calendar          end;

  public Container(Calendar start, Calendar end)
  {

    this.start = start;
    this.end = end;

  }

  public Calendar getStart()
  {
    return start;
  }

  public Calendar getEnd()
  {
    return end;
  }
}

Bigger container:

    public class BiggerContainer
{
  private static final long    serialVersionUID = 1L;

  private ArrayList<Container> containerList    = new ArrayList<Container>();

  public void init()
  {

    int i = 0;

    long max = 604800000;

    long nu = Calendar.getInstance().getTimeInMillis();

    Calendar startC = Calendar.getInstance();

    Calendar endC = Calendar.getInstance();

    while (i <= 5)
    {

      startC.setTimeInMillis(nu);
      endC.setTimeInMillis(nu + max);
      System.out.println("At creation time: " + startC.getTimeInMillis() + " / " + endC.getTimeInMillis());
      containerList.add(new Container(startC, endC));

      nu += max;
      i++;
    }
  }

  public void show()
  {

    for (Container c : containerList)
    {

      System.out.println("Start millis: " + c.getStart().getTimeInMillis() + " end millis "
          + c.getEnd().getTimeInMillis());
    }
  }

  /**
   * TEST
   * 
   * @param args
   */
  public static void main(String[] args)
  {

    BiggerContainer bc = new BiggerContainer();

    bc.init();

    bc.show();
  }

}

Output:

At creation time: 1336480993036 / 1337085793036
At creation time: 1337085793036 / 1337690593036
At creation time: 1337690593036 / 1338295393036
At creation time: 1338295393036 / 1338900193036
At creation time: 1338900193036 / 1339504993036
At creation time: 1339504993036 / 1340109793036


Start millis: 1339504993036 end millis 1340109793036
Start millis: 1339504993036 end millis 1340109793036
Start millis: 1339504993036 end millis 1340109793036
Start millis: 1339504993036 end millis 1340109793036
Start millis: 1339504993036 end millis 1340109793036
Start millis: 1339504993036 end millis 1340109793036

As you can see during the creation of the Container instances in the init() method the Calendar instances provide the correct amount of millis, while in the show method, they print all the same millis...

Do you have any idea? I have the impression that its a very newby mistake, but i cant figure out where i'm doing wrong

You are reusing the same instance of Calendar (startC and endC) for all your container's. Either make a "clone"/"copy" of the calendar in your constructor or create the calendar instances in your loop.

  public Container(Calendar start, Calendar end)
  {

    this.start = (Calendar) start.clone();
    this.end = (Calendar) end.clone();
  }

or

while (i <= 5)
{
  Calendar startC = Calendar.getInstance();
  Calendar endC = Calendar.getInstance();
  startC.setTimeInMillis(nu);
  endC.setTimeInMillis(nu + max);
  System.out.println("At creation time: " + startC.getTimeInMillis() 
          + " / " + endC.getTimeInMillis());
  containerList.add(new Container(startC, endC));

  nu += max;
  i++;
}

You could store the timestamps in the Container object like

containerList.add(new Container(startC.getTime(), endC.getTime()));

then you won't have a problem re-using the calendar instance. And this will be more efficient as I think.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM