2017-07-24 67 views
1

我碰到這個問題我也很沮喪。這裏是正在發生的事情的要點:Arraylist當它不應該被分類?

import static java.lang.System.*; 
import java.util.ArrayList; 
public class Test { 
    public static void main(String[] args) { 
     ArrayList<Integer> list = new ArrayList<Integer>(); 
     list.add(12); 
     list.add(19); 
     list.add(442); 
     list.add(3); 
     list.add(1); 
     list.add(9); 
     out.println(list.toString()); 
     out.println(bubbleSort(list)); 
     out.println(list.toString()); 
    } 
    public static int bubbleSort(ArrayList<Integer> num) { 
     int j; 
     boolean flag = true; 
     int temp; 
     while(flag) { 
      flag = false; 
      for(j = 0; j < num.size() - 1; j++) { 
       if(num.get(j) > num.get(j + 1)) { 
        temp = num.get(j); 
        num.set(j, num.get(j + 1)); 
        num.set(j + 1, temp); 
        flag = true; 
       } 
      } 
     } 
     return num.get(0); 
    } 
} 

輸出是:

[12, 19, 442, 3, 1, 9] 1 [1, 3, 9, 12, 19, 442]

爲什麼當我打電話的方法bubbleSort() ArrayList的list越來越排序?應該不是的方法制作的list實例時,我稱其爲bubbleSort(list),而不是排序list本身是它的範圍之內?我只想bubbleSort通過製作實例的list,使用冒泡排序該實例,並返回一個實例的第一個值來獲得list的最小值。我錯過了真正明顯的東西嗎?我已經得到了真的很累從我沮喪過這個問題......

+0

重複? https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value – assylias

+0

在Java中,你用'new'關鍵字創建了一個新實例,並且你只做了它一次在你的代碼片段中,在main()中。 –

+1

@assylias:我們確實需要一個「什麼是對象引用」的規範,它根本不會涉及整個傳遞過程,因爲它與人們不理解這個問題的95%是無關的。 :-) –

回答

0

NUM一直保存由參而不是價值,所以你需要做的是代碼

import static java.lang.System.*; 
import java.util.ArrayList; 
public class Test { 
    public static void main(String[] args) { 
     ArrayList<Integer> list = new ArrayList<Integer>(); 
     list.add(12); 
     list.add(19); 
     list.add(442); 
     list.add(3); 
     list.add(1); 
     list.add(9); 
     out.println(list.toString()); 
     out.println(bubbleSort(list)); 
     out.println(list.toString()); 
    } 
    public static int bubbleSort(ArrayList<Integer> num) { 
     //copy the array list to new array list 
     ArrayList<Integer> numtemp = new ArrayList<Integer>(num); 
     int j; 
     boolean flag = true; 
     int temp; 
     while(flag) { 
      flag = false; 
      for(j = 0; j < numtemp.size() - 1; j++) { 
       if(numtemp.get(j) > numtemp.get(j + 1)) { 
        temp = numtemp.get(j); 
        numtemp.set(j, numtemp.get(j + 1)); 
        numtemp.set(j + 1, temp); 
        flag = true; 
       } 
      } 
     } 
     return numtemp.get(0); 
    } 
} 
+0

正是我需要的,謝謝。我的課程sci課程從來沒有教給我關於通過引用傳遞和按價值傳遞的信息......猜測我有一些閱讀要做。 – parrot15

+0

@ parrot15:只是要清楚:這是**不**通過引用。 「引用傳遞」是一種術語,指的是傳遞對*變量*的引用,因此被調用的方法可以伸出並更改變量中的值。 Java從來沒有這樣做。 Java確實有對象引用,但是它們是像其他所有東西一樣通過值傳遞的。 –

4

不應該該方法是製作list實例時,我稱其爲bubbleSort(list),而不是排序list本身是它的範圍之內?圍繞指物體(稱爲對象引用)不涉及複製對象,就在值的值

號傳。

的值在變量list是一個對象的引用,它告訴JVM其中該列表對象是在存儲器中。 (我們從來沒有看到實際的價值,但認爲他們是號碼,如int秒;。他們表現得完全像他們一樣),如果傳遞的值轉換成一個方法,該方法接收值的副本(對象引用)  —但該對象引用仍然指向同一個對象。

這是完全一樣的東西是什麼在這裏發生的情況:

List<String> list1 = new ArrayList<>(); 
List<String> list2 = list1; 

讓我們來分析一下。當我們這樣做

List<String> list1 = new ArrayList<>(); 

new操作使得JVM在內存中創建一個ArrayList,並存儲在list1到該列表的引用(它的唯一標識符的JVM理解):

 
list1<Ref22135>−−−+ 
        | +−−−−−−−−−−−−−−+ 
        +−−−>| (ArrayList) | 
         +−−−−−−−−−−−−−−+ 
         | count: 0  | 
         | capacity: 16 | 
         | ...   | 
         +−−−−−−−−−−−−−−+ 

然後,我們這樣做的時候:

List<String> list2 = list1; 

該值(如上文所示Ref22135,但同樣的,我們從來沒有看到他們)是複製list2

 
list1<Ref22135>−−−+ 
        | +−−−−−−−−−−−−−−+ 
        +−−−>| (ArrayList) | 
        | +−−−−−−−−−−−−−−+ 
list2<Ref22135>−−−+ | count: 0  | 
         | capacity: 16 | 
         | ...   | 
         +−−−−−−−−−−−−−−+ 

我們現在必須對單個對象的引用的兩個副本,而不是兩個對象。

出於同樣的原因,傳遞到listbubbleSort拷貝list變量(Ref22135或其他)的bubbleSort參數,而不是列表本身。

+0

這使得現在更有意義,謝謝。儘管我沒有明白爲什麼他們這樣做的目的,所以當我通過list到'bubbleSort()'它使_memory address_的一個實例,而不是列表本身的值。 – parrot15

+0

@ parrot15:每次將它傳遞給一個方法時複製一個對象將**大量低效(並且不要忘記它必須是深層複製,根據定義)。而複製引用是複製4到8個字節(到JVM寄存器或堆棧中)的問題。 –