2

我有两个问题:
首先:
我有一个返回 HashMap 的函数。为了读取返回值,我这样写:

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

如果函数返回一个 HashSet,我也会这样做。

    HashSet<Integer> hs=my_func();

我想知道是否以这种方式将返回的值复制到hs中,或者我应该为它写一个深拷贝,或者我应该这样写:HashSet hs=new HashSet(my_func()); HashMap hm=new HashMap(my_func2());

第二个问题:
我通过调用 make_matrix_funciton 创建一个矩阵。矩阵woule 是一个二维数组,包含:
[0 1 1
0 0 0
0 0 0]
然后我将此矩阵提供给 sort_vec,并在此函数中更改矩阵的元素。我认为java不是基于指针的,所以当我从sort_vec出来时,矩阵应该是原来的样子。但是,变了!它是
[0 0 0
0 0 0
1 1 0]
,它显示了在 sort_vec 函数中对其应用的更改。这是否正常,如果是,我应该怎么做才能防止它。下面的代码是可编译的。

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;
    }
4

2 回答 2

6

Java 总是通过引用传递对象,因此如果您从函数返回 HashMap-Object,则该引用将传递给示例中的 hs 变量。将 HashSet 传递给新 HashSet 实例的构造函数将不起作用。它将创建一个新的 HashSet,其对象引用与原始对象引用相同。如果您修改其中一个对象,则更改也将出现在所有其他参考点上。

如果您想完全分离副本,您将需要自己的深度复制方法,因为在clone() 方法的 JavaDoc 中它说:

返回此 HashSet 实例的浅表副本:元素本身未被克隆。

数组也是如此。每个数组都是一个对象,所以如果你修改一个元素,它会被所有对该数组的引用修改。要创建延迟副本,请使用System.arrayCopy

于 2012-04-23T23:32:53.773 回答
2

您误解了 Java 的引用是如何工作的。

在第一部分中,您的对象将是对 HashMap 的引用 - 即,您从函数返回的任何对象

在第二部分中,您将传递对 int[][] 的引用,当它是基元数组时,它不是按值传递。因此,您的函数将修改数组。如果您想要一个不修改输入数组的函数,则需要复制传入函数的内容,或者在将数组传递给函数之前需要复制数组。

Java 排序例程中的行为是它们修改了原始数组。

总之,没有办法在 Java 中“按值传递”对象或数组。如果您想要这种行为,您必须手动克隆(例如,复制)对象或使用@user3001 的建议

弄清楚这一点后,您可能还想阅读以下内容:http: //javadude.com/articles/passbyvalue.htm

于 2012-04-23T23:35:19.393 回答