2012-04-23 31 views
2

我有兩個問題:
第一:
我有一個函數返回一個HashMap。要讀取返回值,我這樣寫:如何複製hashset和hashmap,以及Java使用指針?

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

我這樣做,如果函數返回一個HashSet。

HashSet<Integer> hs=my_func(); 

我想知道如果這樣返回的值複製到HS,或者我應該寫了深刻的副本,否則我應該寫這樣的: HashSet的HS =新的HashSet(my_func,並將() ); HashMap hm = new HashMap(my_func2());

第二個問題:
我通過調用make_matrix_funciton來創建一個矩陣。矩陣woule是含有2維數組:
[0 1 1
0 0 0]
然後我給這個矩陣sort_vec,並且在該函數矩陣變化的元件。我認爲java不是基於指針的,所以當我從sort_vec出來時,矩陣應該和原來一樣。但是,它已經改變了!它是
[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; 
    } 
+1

是兩個問題有關嗎?如果不是的話,你應該問他們兩個不同的問題。 – twain249 2012-04-23 23:32:35

+3

我認爲他們可以算作相關的,因爲答案非常相似。 – user3001 2012-04-23 23:33:31

+0

你需要*副本嗎?如果是這樣,你確定嗎? – 2012-04-23 23:34:45

回答

6

的Java總是按引用傳遞的對象,因此,如果您從一個函數返回一個HashMap對象時,參考將被傳遞到HS變量在你的榜樣。將HashSet傳遞給新HashSet實例的構造函數將不起作用。它將創建一個新的HashSet,其中具有與原始對象相同的對象引用。如果您修改其中一個對象,則更改也會出現在所有其他參考點上。

如果你想完全分離的副本,你會因爲JavaDoc for the clone() method它說需要有自己的深複製方法:

返回此HashSet實例的淺表副本:本身不被複制的元素。

數組也是如此。每個數組都是一個對象,所以如果你修改了一個元素,它將被修改爲對這個數組的所有引用。要創建延期副本,請使用System.arrayCopy

+1

之內修改一個尼特:java總是按值傳遞。在對象的情況下,它的參考值。有一個微妙的區別。 http://javadude.com/articles/passbyvalue.htm – marathon 2014-06-30 23:09:49

2

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

在第一部分中,你的對象將是一個HashMap的引用 - 也就是說,不管對象你從功能

返回在第二部分中,要傳遞的引用爲int [] [ ],當它是一個基元數組時,它不會傳值。因此,你的函數將修改數組。如果你想要一個不修改輸入數組的函數,你需要將傳入的函數拷貝到函數中,或者在將數組傳遞給函數之前,需要複製該數組。

Java排序例程中的行爲是它們修改原始數組。

總而言之,沒有辦法在Java中'按值傳遞'對象或數組。如果你想這種行爲,你必須克隆(例如,副本)對象手動或使用@ user3001的建議

一旦你弄清楚了這一點,你可能需要閱讀這個問題,以及:http://javadude.com/articles/passbyvalue.htm

+0

所以你認爲我應該定義一個Integer類型的數組而不是原始類型? – Pegah 2012-04-23 23:37:15

+0

沒有。保持。這沒關係。你想讓函數返回一個不影響原始數組的複製數組嗎? – dfb 2012-04-23 23:38:31

+0

變量mat應該是一個新數組,它是矩陣的修改版本。但是我不希望矩陣在int [] [] mat = sort_vec(3,matrix,indexes)之後進入行時被改變。在sort_vec內更改矩陣時可以。 – Pegah 2012-04-23 23:39:48