简体   繁体   English

是否有必要在Java中深度复制数组?

[英]Is it necessary to deep copy an array in java?

As far as I know and researched, arrays in Java are not objects but they're reference-types. 据我所知和研究,Java中的数组不是对象,而是引用类型。 My doubt is, when I want to return an array should I return a deep copy (like you would do with an object) with a clone() method for example, or can I return the variable countaining the array like it was a simple-type variable (ie. int or double) with a get method? 我的疑问是,当我想返回一个数组时,我应该使用例如clone()方法返回一个深拷贝(就像您对一个对象所做的那样clone() ,还是可以像返回一个简单的数组那样返回计数数组的变量?用get方法输入变量(即int还是double)? For clarification porpuses, I will insert an example code to expose this situation: 为了澄清,我将插入一个示例代码来揭示这种情况:

public class List
{
    // Instance Variables ----------
    private int[] list1;
    private int[] list2;

   // Constructors ----------
   public List()
   {
     list1 = new int[0]; list2 = new int[0];
   }
   public List(List x)
   {
       list1 = x.getList1();
       list2 = x.getList2();

    }

    // Get methods
    public int[] getList1()
    {
        return list1;
    }

    public int[] getList2()
    {
        return list2;
    }

    // Set methods
    public void setList1(int size)
    {
        list1 = new int[size];
    }

     public void setList2(int size)
    {
        list2 = new int[size];
    }
      // Compare reference between an array and the instance variables
      public boolean equals (int[] x)
    {
        if ( x == list1 || x == list2)
        return true;
        else
        return false;
    }
}

And now I have a TestClass the uses class List like this: 现在,我有一个TestClass,它的使用类List是这样的:

List listx = new List();
int[] listy = listx.getList2();
boolean test = listx.equals(listy);
System.out.printf("Result: " + test );

With this said, when I use the method equals to see if the two arrays share the same reference or adress, I get always the result true!! 如此说来,当我使用equals方法查看两个数组是否共享相同的引用或地址时,总是得到正确的结果! Am I breaking OOP basic principals with this? 我是否以此打破OOP基本原理? Will I loose control because listy is pointing to listx instance variable? 我会因为listy指向listx实例变量而失去控制权吗? Well, I'm really confused with this and I don't know if this is right(being array a non-instantiable class) or If I should send some kind of deepcopy insted of shallow using a Clone method in other to ensure that all basic OOP principals are fulfilled, and with this principals I mean that the class method should be acessed only by the API and that the internal state(instance variables) can only be acessed by the class itself. 好吧,我真的对此感到困惑,我不知道这是否正确(将数组作为非实例化的类),或者是否应该使用其他方法使用Clone方法发送某种浅层的Deepcopy来确保所有基本的OOP原则已得到满足,用这个原则,我的意思是说,类方法只能由API访问,而内部状态(实例变量)只能由类本身访问。

If you want the invoker of the method to be able to modify the original array, you don't need to do a copy. 如果希望方法的调用者能够修改原始数组,则无需执行复制操作。 Otherwise, you do. 否则,您会这样做。

Check your implementation of equals(). 检查equals()的实现。 It should be reflexive, symmetric, and transitive , which is not the case on yours. 它应该是自反的,对称的和可传递的 ,而您的情况并非如此。

You are not breaking OOP principals. 您没有违反OOP主体。 However, you are breaking principals of functional programming. 但是,您正在打破函数式编程的原理。 Functional programming views leaking of access as losing of control. 功能编程将访问泄漏视为失去控制。

Whether or not you want to practice functional programming is up to you, Java doesn't take a stance in that matter. 无论您是否要练习函数式编程,都由您决定,Java对此不采取任何立场。

You may want to consider if it's important not to leak access for this particular class. 您可能要考虑不要泄漏此特定类的访问权限是否重要。 If you find it important not to leak access then make this class immutable. 如果您发现不要泄漏访问权限很重要,请将该类设为不可变的。

You can also guard the instance variables. 您还可以保护实例变量。 In this scenario any possible changes to the variables must be handled by the instance class. 在这种情况下,变量的任何可能更改都必须由实例类处理。 However, the instance could be modified from separate contexts and result in loss of control. 但是,可以从单独的上下文中修改实例,并导致失去控制。 For this reason functional programming only allows immutable classes. 因此,函数式编程仅允许不可变的类。

It depends on your use-case if you want to deep copy or not. 是否要深层复制取决于您的用例。 If your elements are immutable you normally not need to do a deep copy. 如果您的元素是不可变的,通常不需要进行深层复制。 If they can change, it depends if you want to see the changes in your receiver of the copy or not. 如果可以更改,则取决于您是否要在副本的接收方中查看更改。 Typically when you want a snapshot of the given data you will have to deep copy it. 通常,当您想要给定数据的快照时,必须深度复制它。 However keep in mind that Arrays are most of the time not a good argument or return type for APIs anyway. 但是请记住,在大多数情况下,数组不是API的好参数或返回类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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