如何替换java集合中的对象?

nor*_*771 2 java iteration collections

我正在尝试用新的修改版本替换集合中的元素。下面是简短的代码,旨在演示我想要实现的目标。

整个想法是我有一个由其他对象的集合组成的对象。在某个时间点,我预计集合中的这个对象(在我的示例手机中)可能需要一些修改,并且我只想修改一个地方的代码。

我知道为了更新对象的属性,我可以在迭代集合时使用 setter,如下所示。但也许有更好、更通用的方法来实现这一目标。

public class Customer {
    private int id;
    private Collection<Phone> phoneCollection;
    public Customer() {
        phoneCollection = new ArrayList<>();
    }
//getters and setters    

}
Run Code Online (Sandbox Code Playgroud)

和电话类

public class Phone {
    private int id;
    private String number;
    private String name;
//getters and setters    
}
Run Code Online (Sandbox Code Playgroud)

public static void main(String[] args) {
        Customer c = new Customer();

        c.addPhone(new Phone(1, "12345", "aaa"));
        c.addPhone(new Phone(2, "34567", "bbb"));
        System.out.println(c);

        Phone p = new Phone(2, "9999999", "new name");

        Collection<Phone> col = c.getPhoneCollection();
        for (Phone phone : col) {
            if (phone.getId() == p.getId()) {
//             This is working fine
//                phone.setNumber(p.getNumber());
//                phone.setName(p.getName());

//              But I'd like to replace whole object if possible and this is not working, at least not that way
                  phone = p;
            }
        }
        System.out.println(c);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样可以达到我想要的效果吗?我尝试了复制构造函数的想法和我在网上搜索发现的其他方法,但它们都没有像我预期的那样工作。

编辑1

读了一些评论后我有了一个想法

我将以下方法添加到我的 Phone 类中

public static void replace(Phone org, Phone dst){
    org.setName(dst.getName());
    org.setNumber(dst.getNumber());
}
Run Code Online (Sandbox Code Playgroud)

现在我的 foreach 部分看起来像这样

    for (Phone phone : col) {
        if (phone.getId() == p.getId()) {
            Phone.replace(phone, p);
        }
    }
Run Code Online (Sandbox Code Playgroud)

它确实完成了这项工作。现在,如果我更改 Phone 类属性,我只需要更改该方法。您认为这样解决问题可以吗?

Ted*_*opp 5

在迭代集合时不应修改集合;这可能会为您赢得ConcurrentModificationException. 您可以扫描集合以查找第一个与您的搜索条件匹配的对象。然后您可以退出循环,删除旧对象,并添加新对象。

Collection<Phone> col = c.getPhoneCollection();
Phone original = null;
for (Phone phone : col) {
    if (phone.getId() == p.getId()) {
        original = phone;
        break;
    }
}
if (original != null) {
    Phone replacement = new Phone(original);
    replacement.setNumber(p.getNumber());
    replacement.setName(p.getName());
    col.remove(original);
    col.add(replacement);
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以声明更具体的集合类型,例如 a List,它允许您使用索引,这将使替换步骤更加高效。

如果每部电话的电话 ID 都是唯一的,则应考虑使用将Map<Integer, Phone>每个电话 ID 映射到相应电话的 。(或者,您可以使用某种第三方稀疏数组结构,该结构不涉及将每个 ID 装箱到一个 中Integer。)当然,如果您的 ID 不是唯一的,那么您可能需要修改上面的内容以收集辅助 ID所有匹配手机的集合(并重新考虑现有代码的逻辑)。