gpt4 book ai didi

java - 为什么按 Id 对对象列表进行分组仅在该函数中第一次调用时有效?

转载 作者:行者123 更新时间:2023-12-02 11:56:30 25 4
gpt4 key购买 nike

我想将对象列表(来自数据库)按其元素进行分组,这与以下简化代码配合使用效果良好:

List<MyClass> sqlResultList;
List<MyClass> resultList;

public void applyMerge() {

Map<Integer, List<MyClass>> map =
sqlResultList.stream().collect(Collectors.groupingBy(MyClass::getIdItem));

resultList = new ArrayList<>();
for (Integer IdItem : map.keySet()) {

List<MyClass> tmp = map.get(IdItem);

if (tmp.size() > 0) {

MyClass head = tmp.get(0); // seems to create just a reference

for (int i = 1; i < tmp.size(); i++) {

MyClass obj = tmp.get(i);
head.setMinutes(head.getMinutes() + obj.getMinutes());

}

resultList.add(head);

}
}
}

我遇到的唯一问题是,如果我记得 applyMerge() 函数,它会将所有值添加到之前的总和值之上。我以为对象MyClass head只是一个临时对象,但它似乎是一个引用tmpmap

有什么提示我的误解是什么吗?

ps:我可以从数据库更新sqlResultList,但我想避免这种情况,因为数据本身没有改变。

最佳答案

您的 head 对象是对原始列表中的对象的引用。它不是副本,因此您对该对象所做的任何修改也将被对该对象的任何其他引用看到。

您将需要克隆该对象:

MyClass head = tmp.get(0).clone();

克隆的方法各不相同,但典型的方法是重写 Object#clone() 方法。在此方法中,您将创建 MyClass 的新实例,然后复制所需的所有属性。例如:

public class MyClass {
private int minutes;

public MyClass clone() {
MyClass clonedInstance = new MyClass();
clonedInstance.setMinutes(getMinutes());
return clonedInstance;
}

public int getMinutes() {
return this.minutes;
}

public void setMinutes(int minutes) {
this.minutes = minutes;
}
}

如果您有其他属性,那么您将需要确保您也了解任何必要的深度克隆。例如,如果您有一个可变类型的属性(例如 List),那么您可能需要克隆该属性,等等。

许多标准 JDK 类型也提供了自己的 clone 方法,例如 ArrayList

关于java - 为什么按 Id 对对象列表进行分组仅在该函数中第一次调用时有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47562555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com