首页 > 解决方案 > 为什么 ArrayList.add() 会修改添加的对象?

问题描述

当我将对象添加到 ArrayList 时,它会被 chenged。

我正在尝试制作一个 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;
    }

非常感谢您的时间。

标签: javaarraylist

解决方案


三个无法解释的事件是:

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语句的这三个事件(因为打印了“事件存在”。)。

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

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

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

您在此处所做的是将对新对象的引用添加到列表中,然后(3 次)检索它,更改它,然后再次向此列表添加对同一对象的附加引用。


推荐阅读