java - 为什么 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;
}
非常感谢您的时间。
解决方案
三个无法解释的事件是:
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 次)检索它,更改它,然后再次向此列表添加对同一对象的附加引用。
推荐阅读
- javascript - Vue.js 3 - 通过计算属性启用/禁用表单元素
- html - 如何在打印页面时删除 .tab-pane 边框?
- java - Gson JsonArray to List long 类型变成科学记数法
- git - git flow 扩展不断要求标签
- r - 在 R 闪亮的 kable 列名称中添加文本下标
- javascript - Sequelize 不会在 where 中连接 Ands
- python - 运行自定义模型的中间表示 (IR),OpenVino
- python-3.x - mypyc 有没有办法编译代理对象?
- reactjs - 单击按钮显示 GeoJSON 类的新 geojson 数据
- docker - 如何在带有 docker 和设置访问控制的 Windows 上使用 Vcxsrv