为什么ArrayList.add()修改添加的对象?

时间:2019-08-13 18:37:07

标签: java arraylist

当我将一个对象添加到ArrayList时,它就会变色。

我正在尝试制作Java fx议程应用程序,因此我需要将表中想要的对象的ArrayList传递给ObservableList。

问题恰好发生在此功能中,位于tableToday.add(ret);

public ArrayList<SkEvent> getTableToday() {
        LocalDateTime clock = LocalDateTime.of(LocalDate.now(), LocalTime.of(0,0));
        while (clock.until(LocalDateTime.of(LocalDate.now(), LocalTime.of(23,59)), ChronoUnit.MINUTES)>0){
            System.out.println("clock: "+clock.toLocalTime().toString());

            SkEvent ret = new SkEvent(LocalDate.now(), clock.toLocalTime());

            if(existsEvent(clock)){
                System.out.println("Event exists.");

                ret = getEvent(clock);
                ret.setLocalDateTime(clock);
            }


            tableToday.add(ret);
            System.out.println("Added event "+ ret.getName() + " at "+ret.getTime().toString());
            LocalDateTime updatedClock = clock.plusMinutes(gap);
            clock = updatedClock;

        }

这是输出的一部分:

clock: 21:00
Added event  at 21:00
clock: 21:30
Added event  at 21:30
clock: 22:00
Event exists.
Added event e at 22:00
clock: 22:30
Event exists.
Added event e at 22:30
clock: 23:00
Event exists.
Added event e at 23:00
clock: 23:30
Added event  at 23:30
Times in the table: 
21:00
21:30
23:00
23:00
23:00
23:30

您可以看到我在22:00、22:30和23:00添加了3个事件,但是在ArrayList上输出事件时间是23:00的3倍

它应该输出

Times in the table: 
21:00
21:30
22:00
22:30
23:00
23:30

此外,这是SkEvent类:

public class SkEvent{
    private LocalDate date;
    private LocalTime time;
    private String name;
    private String description;

    public SkEvent(LocalDate date, int hour, int minute, String name, String description) {
        this.date = date;
        this.time = LocalTime.of(hour, minute);
        this.name = name;
        this.description = description;
    }

    public SkEvent(LocalDate date, LocalTime time){
        this.date = date;
        this.time = time;
        this.name = "";
        this.description = "";
    }

    public LocalDateTime getLocalDateTime(){
        return LocalDateTime.of(getDate(), getTime());
    }

    public SkEvent setLocalDateTime(LocalDateTime localDateTime){
        this.date = localDateTime.toLocalDate();
        this.time = localDateTime.toLocalTime();

        return this;
    }

    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public LocalTime getTime() {
        return time;
    }

    public void setTime(LocalTime time) {
        this.time = time;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

getEvent()方法:

private Map<SkEvent, LocalDateTime> actualEvents = new HashMap();
//(...)
    private SkEvent getEvent(LocalDateTime clock) {
        for(Map.Entry<SkEvent, LocalDateTime> entry: actualEvents.entrySet()){
            if(!entry.getKey().getLocalDateTime().isAfter(clock) && !entry.getValue().isBefore(clock)){
                return entry.getKey();
            }
        }
        return null;
    }

非常感谢您的宝贵时间。

1 个答案:

答案 0 :(得分:1)

我没有足够的声誉来发表评论,所以我将其发布为答案:

三个无法解释的情况是:

clock: 22:00
Event exists.
Added event e at 22:00
clock: 22:30
Event exists.
Added event e at 22:30
clock: 23:00
Event exists.
Added event e at 23:00
在控制台上可以看到

:对于这三个事件,您输入了if语句(因为打印了“ Event exist。”。)。

if(existsEvent(clock)){
  System.out.println("Event exists.");
  ret = getEvent(clock);
  ret.setLocalDateTime(clock);
}

我只能猜测所使用的函数在做什么,但是我假设如果存在一个existsEvent(clock)且其时间和日期说明符与SkEvent(实际日期)相同的clock返回true )(在上述三种情况下,显然是这样)。 getEvent(clock)然后检索此SkEvent并用它覆盖ret变量。然后更改retret.setLocalDateTime(clock))。

tableToday.add(ret)确实在列表中添加了引用(指向SkEvent)。这意味着,之后更改SkEvent对象,也将更改其在列表中的出现次数,因为它只是指向实际(更改的)对象的指针。

您在此处所做的操作是将对新对象的引用添加到列表中,然后(3次)检索它,对其进行更改,然后将对相同对象的其他引用再次添加到该列表中