当前位置: 首页 > 知识库问答 >
问题:

如何在ArrayList(RecyclView)中克隆对象?

蔚和安
2023-03-14

我试图在RecyclerView使用的ArrayList中创建一个对象的克隆,我已经用Clonable扩展了我的实体,但是当我编辑克隆的对象时,甚至修改了原始对象。

什么将是正确的方式来克隆/复制一个对象在回收器视图?

实体:

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

}

实体变量:

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

活动:

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

然后,当一个RecyclerView项目被滑动时,将该位置传递到一个修改对话框,在该对话框中,我可以对该对象进行一些编辑。

编辑:

通过深入研究,我发现只有当实体(变体数组)中存在一些子元素时,问题才会持续存在,否则克隆将按其必须的方式工作。

因此,如果我的实体在变体中有任何对象,并且它是克隆的,那么如果我在两个对象中的一个对象中添加一个新变体,两个对象都会得到它。。

编辑2:

正如@Ocasin指出的那样,克隆的Prodotti仍然指向原始的Varianti列表。

通过从克隆实体中清除Varianti列表,克隆Varianti列表本身并将其设置在克隆实体的Varianti列表中,我能够解决这个问题。

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

共有1个答案

房子昂
2023-03-14

我认为当你克隆你的Prodotti-对象时,variantsArrayList的引用被克隆了,所以克隆的Prodotti-对象中的variants字段指向与原始Prodotti-对象的variants-字段相同的列表。

我建议使用复制构造函数而不是clone(),然后手动处理变体-字段的复制;

 类似资料:
  • 问题内容: 如何克隆 Java并同时在Java中克隆其项目? 例如,我有: 我希望其中的对象与狗列表中的对象不同。 问题答案: 你将需要迭代这些项目,然后逐个克隆它们,然后将克隆放入结果数组中。 显然,要使该方法起作用,你将必须使你的类实现接口并重写该方法。

  • 本文向大家介绍如何复制或克隆Java ArrayList?,包括了如何复制或克隆Java ArrayList?的使用技巧和注意事项,需要的朋友参考一下  java.util.ArrayList类的 clone()方法返回此ArrayList实例的浅表副本(即,不复制元素本身)。使用此方法,可以将一个数组列表的内容复制到另一个数组列表。 示例 输出结果

  • 问题内容: 如果克隆数组,我将使用 我想知道如何在nodejs中克隆对象。 问题答案: 对于不需要压缩每一滴性能的实用程序和类,我经常作弊,只是使用JSON执行深层复制: 这不是唯一的答案,也不是最优雅的答案。所有其他答案都应考虑成为生产瓶颈。但是,这是一个快速而肮脏的解决方案,非常有效,并且在大多数情况下(我会克隆属性的简单哈希值)很有用。

  • 我有下面的java代码,当我稍后尝试访问MiscDoc对象时,它似乎是空的。我找不到答案。NotesDocument上的clone()方法。 if语句只被访问一次 我该如何解决这个问题

  • 问题内容: 在node.js中克隆对象的最佳方法是什么 例如,我想避免以下情况: 该对象很可能包含复杂的类型作为属性,因此简单的for(var1 in obj1)无法解决。我需要自己编写一个递归克隆吗,还是内置了一些我看不到的东西? 问题答案: 可能性1 简洁的深层副本: 可能性2(已弃用) 注意: 现在,Node.js文档中将该解决方案标记为不推荐使用: 从未打算在内部Node.js模块之外使用

  • 本文向大家介绍如何实现对象克隆?相关面试题,主要包含被问及如何实现对象克隆?时的应答技巧和注意事项,需要的朋友参考一下 实现 Cloneable 接口并重写 Object 类中的 clone() 方法。 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。