传递值而不是通过参考传递复制粘贴功能

时间:2014-12-18 02:06:53

标签: java java-ee hashset oracle-adf

我在HashSet中传递值有问题。每次我想从表格内复制数据并将数据粘贴到其他页面上。但我面临的问题是它最终会通过引用传递而不是传递值。这意味着当我点击粘贴'按钮数据是新的1而不是旧的1,假设保存在我的hashset中。请告知我应该如何解决这个问题非常感谢。谢谢我的代码:

  static HashSet<ScmTelephoneDetailsViewRowImpl> copy_set = new HashSet<ScmTelephoneDetailsViewRowImpl>(); 

      public void copy_data(ActionEvent actionEvent){


    for(int z=0;z<scm_details_row.getRowCount();z++){

        ScmTelephoneDetailsViewRowImpl telephone_accounting_details_9 =(ScmTelephoneDetailsViewRowImpl)scm_details_row.getRowAtRangeIndex(z);
        copy_set.add(telephone_accounting_details_9);  

    }       
    System.out.println("copy_set " + copy_set.size()); 
    System.out.println("copy_set " + copy_set.getClass());       
}

public void paste_data(ActionEvent actionEvent){         

    System.out.println("Paste Data");
    Iterator setIterator =copy_set.iterator(); 
        while(setIterator.hasNext()){

         ScmTelephoneDetailsViewRowImpl get_interator = (ScmTelephoneDetailsViewRowImpl)setIterator.next();

            //System.out.println("copy_set "+ setIterator.next());           
            System.out.println("data inside "+ get_interator.getTelephoneUser());            
        }   

}

2 个答案:

答案 0 :(得分:2)

在Java中,没有办法按值传递引用类型:只能使用基本类型和引用本身。当你想要一个复制语义时,你需要自己实现它。

您的代码中发生的事情是您正在制作一套浅色的副本:

for(int z=0;z<scm_details_row.getRowCount();z++){
    ScmTelephoneDetailsViewRowImpl telephone_accounting_details_9 =(ScmTelephoneDetailsViewRowImpl)scm_details_row.getRowAtRangeIndex(z);
    copy_set.add(telephone_accounting_details_9);
}

上面的循环使您成为一个新的集合,从某种意义上说,如果您添加或删除copy_set中的任何内容,原始的scm_details_row将无法看到差异。但是,如果更改任何ScmTelephoneDetailsViewRowImpl个对象,原始集合中的对象也会更改,因为这是同一个对象。

要解决此问题,请创建一个复制构造函数或实现某种“克隆”方法以进行“深度”复制,并将深层副本插入copy_set

for(int z=0;z<scm_details_row.getRowCount();z++){
    ScmTelephoneDetailsViewRowImpl telephone_accounting_details_9 =
        (ScmTelephoneDetailsViewRowImpl)scm_details_row.getRowAtRangeIndex(z);
    ScmTelephoneDetailsViewRowImpl copyRow =
        new ScmTelephoneDetailsViewRowImpl(telephone_accounting_details_9);
    copy_set.add(copyRow);
}

为了使其正常工作,您需要为ScmTelephoneDetailsViewRowImpl类定义“复制构造函数”:

public ScmTelephoneDetailsViewRowImpl(ScmTelephoneDetailsViewRowImpl other) {
    // Initialize this object using the data from the object "other" passed as the parameter
    this.someFieldOne = other.someFieldOne;
    this.someFieldTwo = other.someFieldTwo;
    // If there are collections in the object, make deep copies of them as well
    ...
}

答案 1 :(得分:0)

显然,ScmTelephoneDetailsViewRowImpl是一个对象,而不是一个简单的值。但我认为你想要的是一个新对象,它与原始对象相同(所有字段都相同)但占用不同的内存。

你有没有像

这样的东西
ScmTelephoneDetailsViewRowImpl temp = telphone_accounting_details_9.clone();
copy_set.add(temp);

你真正想要的是一份深刻的副本。它会手动复制所有字段。

如果您的类ScmTelephoneDetailsViewRow是您可以直接扩展或修改的,那么您可以覆盖从Object继承的clone()函数。

修订:为了在你的对象上调用clone(),它需要实现&#34;接口&#34;叫做Cloneable。但是该界面中没有方法。所以你只需要添加&#34;实现Cloneable&#34;到类定义。假设你控制那个班级。

clone()的默认实现的另一个问题是,如果你的对象包含任何非原始字段(例如数组),那么将会生成指向数组的指针的副本,它将不会创建&# 34;深&#34;复制它生成新数组空间并复制所有数组元素。正如我之前所说,如果您使用@O​​verride clone(),或者根据自己的选择制作新的复制命令,则可以克服这个问题。