How to copy hashset and hashmap, and does the Java use pointers?

怎甘沉沦 提交于 2019-12-11 03:56:21

问题


I have two questions:
First:
I have a function which returns a HashMap. To read the returned value, I write it like this:

    HashMap<Integer,String> hs=my_func2();

I do the same if the function returns a HashSet.

    HashSet<Integer> hs=my_func();

I wanted to know if in this way the returned value is copied into hs, or I should write a deep copy for it or I should write it like this: HashSet hs=new HashSet(my_func()); HashMap hm=new HashMap(my_func2());

Second quesion:
I make a matrix by calling make_matrix_funciton. matrix woule be a 2-dimensional array containing:
[0 1 1
0 0 0
0 0 0]
Then I give this matrix to sort_vec, and in this function the elements of matrix change. I think java is not pointer based, so when I come out of sort_vec, matrix should be as it had been. But, it has changed! It is
[0 0 0
0 0 0
1 1 0]
which shows the changes that had been applied to it inside the sort_vec function. Is it normal and if yes, what should I do to prevent it. The code below is compilable.

public static void main(String args[]) {
        int matrix[][]=new int[3][3];
        matrix=make_matrix("011000000");
        int indexes[]={2,1,0};
        int[][] mat=sort_vec(3,matrix,indexes);
    }

    private static int[][] sort_vec(int motifsize,int [][]mat,int[] indexes)
    {
        int[] main_index={0,1,2};

        int l=indexes.length;
        for (Integer i=0;i<l;i++)
            if(indexes[i]!=main_index[i])
            {
                int j=indexes[i];
                int k=main_index[i+1];
                for(;k<l;k++)
                    if(indexes[k]==main_index[i])
                        break;

                indexes[k]=j;
                mat=exchange(motifsize,mat,j,main_index[i]);
            }
        return mat;
    }
    private static int[][] exchange(int motifsize,int [][]matrix,int x,int y)
    {
        int temp;

        for(int i=0;i<motifsize;i++)
        {   
            temp=matrix[i][x];
            matrix[i][x]=matrix[i][y];
            matrix[i][y]=temp;
        }
        for(int i=0;i<motifsize;i++)
        {   
            temp=matrix[x][i];
            matrix[x][i]=matrix[y][i];
            matrix[y][i]=temp;
        }

        return matrix;
    }
    private static int[][] make_matrix(String id)
    {
        int matrix[][]=new int[3][3];
        int c=0;
        for(int x=0;x<3;x++)
            for(int y=0;y<3;y++)
            {
                if(id.charAt(c)=='1' || id.charAt(c)=='5')
                    matrix[x][y]=1;
                c++;
            }
        return matrix;
    }

回答1:


Java always passes Objects by reference, so if you return a HashMap-Object from a function, the reference will be passed to the hs variable in your example. Passing the HashSet to the constructor of a new HashSet instance will not work. It will create a new HashSet with the same object references as in the original one. If you modify one of these objects, the change will appear on all other reference points, too.

If you want to totally detach the copy, you will need your own method for deep copying because in the JavaDoc for the clone() method it says:

Returns a shallow copy of this HashSet instance: the elements themselves are not cloned.

The same goes for arrays. Every array is an object, so if you modify an element, it will be modified for all references to this array. To create a deferred copy, use System.arrayCopy




回答2:


You are misunderstanding how Java's references work.

In the first part, your object will be a reference to a HashMap - i.e., whatever object you've returned from the function

In the second part, you are passing a reference to an int[][], it is not pass by value when it's an array of primitives. Thus, your function will modify the array. If you want a function that does not modify the input array, you need to copy what is passed in to the function or you will need to copy the array before you pass it to your function.

The behavior in Java sorting routines is that they modify the original array.

In sum, there is no way to 'pass by value' an object or array in Java. If you want this behavior, you have to clone (e.g., copy) the object manually or using @user3001's suggestion

Once you figure this out, you may want to read this as well: http://javadude.com/articles/passbyvalue.htm



来源:https://stackoverflow.com/questions/10289682/how-to-copy-hashset-and-hashmap-and-does-the-java-use-pointers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!