简体   繁体   中英

How to clone an object in ArrayList (RecyclerView)?

I'm trying to create a clone of an object in ArrayList used by RecyclerView, i've yet extended my entity with Clonable but when i edit the cloned object even the original one is modified.

What would be the correct way to clone/duplicate an object in RecyclerView?

Entity:

public class Prodotti implements Serializable, Cloneable {
private final String descProdotto;
private double qta;
private int turno;
private String codice;
private String time;
private String codOP;
private String state;
private String pre;
private ArrayList<Varianti> variants = new ArrayList<>();

    @NonNull
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}

Entity Varianti:

public class Varianti implements Serializable, Cloneable {
    String descrizione;
    private String codice;
    transient BitmapDrawable drawable;
    private String state;
    public String pre;
    public String qta;

    public Varianti(String descrizione, String codice, BitmapDrawable drawable, String state, String pre, String qta) {
        this.descrizione = descrizione;
        this.codice = codice;
        this.drawable = drawable;
        this.state = state;
        this.pre = pre;
        this.qta = qta;
    }

    @NonNull
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Activity:

    ArrayList<Prodotti> listProdotti = new ArrayList<>();

    Prodotti prodotto = listProdotti.get(position);

    @Override
    public void onClickDuplicate() {
        try {
            Prodotti productDuplicate = (Prodotti) prodotto.clone();
            productDuplicate.setState("A");
            listProdotti.add(productDuplicate);
            adapterProdotti.notifyItemInserted(listProdotti.size() - 1);
            recyclerComanda.scrollToPosition(listProdotti.size() - 1);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

Then when a RecyclerView item is swiped pass the position to a modify Dialog where i'm able to make some edits on the object.

EDIT:

By looking deeper i've found that the problem persists only when there are some child elements in the entity (variants array) else the clone works as it has to.

So if my entity has any object in variants and it's cloned then if i add a new variant in one of the two object both will get it..

I think when you clone your Prodotti -Object, the reference to the variants ArrayList is cloned with it, so the variants field in the cloned Prodotti -Object points to the same list as the variants -field of the origninal Proddotti -Object.

I would recommend using a copy-constructor instead of clone() and then handle the copiing of the variants -field manually;

As @Ocasin pointed out the cloned Prodotti was still pointing to the original Varianti lists.

I was able to solve the issue by clearing the Varianti list from the cloned entity and by cloning the Varianti list itself and setting it in Varianti list of the cloned entity.

        try {
            Prodotti productDuplicate = (Prodotti) prodotto.clone();
            productDuplicate.setState("A");

            productDuplicate.setVariantsList(new ArrayList<Varianti>());
            ArrayList<Varianti> varianti = (ArrayList<Varianti>) prodotto.getVarianti().clone();
            productDuplicate.setVariantsList(varianti);
            
            listProdotti.add(productDuplicate);
            adapterProdotti.notifyItemInserted(listProdotti.size() - 1);
            recyclerComanda.scrollToPosition(listProdotti.size() - 1);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM