How can I replace object in java collection

De openkb
Aller à : Navigation, rechercher

Sommaire

Questions

I am trying to replace element in collection with new modified version. Below is short code that aims to demonstrate what I d like to achieve.

The whole idea is that I have one object that consists of collections of other objects. At some point in time I am expecting that this objects in collections (in my example phones) might require some modifications and I d like to modify the code in one place only.

I know that in order to update the object s attributes I can use setters while iterating through the collection as demonstrated below. But maybe there is better, more general way to achieve that.

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

}

and Phone class

public class Phone {
    private int id;
    private String number;
    private String name;
//getters and setters    
}

and

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);
    }
}

Is this possible to achieve what I want? I tried copy constructor idea and other methods I found searching the net but none of them was working like I would expect.

  EDIT 1   

After reading some comments I got an idea

I added the following method to my Phone class

public static void replace(Phone org, Phone dst){
    org.setName(dst.getName());
    org.setNumber(dst.getNumber());
}

and now my foreach part looks like that

    for (Phone phone : col) {
        if (phone.getId() == p.getId()) {
            Phone.replace(phone, p);
        }
    }

And it does the job. Now if I change the Phone class attributes I only need to change that method. Do you think it is OK solving the issue that way?

Answers

You should not modify the collection while you re iterating through it; that s likely to earn you a ConcurrentModificationException. You can scan the collection for the first object that matches your search criterion. Then you can exit the loop, remove the old object, and add the new one.

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);
}

Alternatively, you could declare a more specific type of collection, such as a List, that would allow you to work with indexes, which would make the replacement step much more efficient.

If your phone IDs are unique to each phone, you should consider using a Map<Integer, Phone> that maps each phone ID to the corresponding phone. (Alternatively, you could use some sort of third-party sparse array structure that doesn t involve boxing each ID into an Integer.) Of course, if your IDs aren t unique, then you might want to modify the above to gather a secondary collection of all matching phones (and reconsider the logic of your existing code as well).

Source

License : cc by-sa 3.0

http://stackoverflow.com/questions/36726835/how-can-i-replace-object-in-java-collection

Related

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils