2010-03-06 21 views
27

如何讓我的交換功能在Java中,如果沒有方法,通過它,我們可以通過引用傳遞?有人可以給我一個代碼嗎?如何在java中創建我的交換功能?

swap(int a, int b) 
{ 
    int temp = a; 
    a = b; 
    b = temp; 
} 

但由於Java經過值

+3

如果你想得到這方面的幫助,你必須更具體地陳述你要完成的任務。 –

+1

查看本文:http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html –

+1

Java中的所有參數都是按值傳遞的。 –

回答

14

你不能創建一個方法交換,所以在調用swap(x,y)之後x和y的值將被交換。你可以通過交換它們的contents¹創建可變類這樣的方法,但是這不會改變自己的對象標識,你不能爲這個定義的一般方法。

但是你可以寫在交換一個數組或列表的兩個項目,如果這就是你想要的東西的方法。

¹例如,你可以創建一個交換方法,它採用兩個列表和執行方法之後,名單x將有名單Y的以前的內容,並列出ÿ將列表x的以前的內容。

+4

您可以創建一個[方法](http://stackoverflow.com/questions/2393906/how-do-i-make-my-swap-function-in-java/20600020#20600020),稱爲'y = swap( x,x = y)'交換x和y。 – dansalmo

14

這取決於你想做什麼變化不會被反射回來。這段代碼交換了一個數組的兩個元素。

void swap(int i, int j, int[] arr) { 
    int t = arr[i]; 
    arr[i] = arr[j]; 
    arr[j] = t; 
} 

像這樣的東西交換了等長的兩個int[]的內容。

void swap(int[] arr1, int[] arr2) { 
    int[] t = arr1.clone(); 
    System.arraycopy(arr2, 0, arr1, 0, t.length); 
    System.arraycopy(t, 0, arr2, 0, t.length); 
} 

像這樣交換兩個BitSet的內容(使用XOR swap algorithm):

void swap(BitSet s1, BitSet s2) { 
    s1.xor(s2); 
    s2.xor(s1); 
    s1.xor(s2); 
} 

像這樣的東西交換一些Point類的xy領域:

void swapXY(Point p) { 
    int t = p.x; 
    p.x = p.y; 
    p.y = t; 
} 
+0

是通過引用傳遞的數組? – higherDefender

+0

不是。Java中的所有東西都是按值傳遞的,包括Java中的_references to_ arrays。數組與本例中的任何其他對象沒有區別。 – polygenelubricants

+2

@ D.J .:數組(像所有對象)都是引用類型。這意味着對方法內的對象所做的任何更改都將在外部可見(這也意味着將對象傳遞給方法不會複製對象的內容,因此傳遞1M元素的數組不會複製1M對象)。然而,重新分配引用數組的變量在外部是不可見的(也就是說,如果在方法內部執行類似'arr1 = arr2'的操作,這將不會對外部有任何可見的影響)。 – sepp2k

1

我可能會做一些像下面這樣。當然,有了豐富的Collection類,我無法想象在任何實際的代碼中都需要使用它。

public class Shift { 
    public static <T> T[] left (final T... i) { 
    if (1 >= i.length) { 
     return i; 
    } 
    final T t = i[0]; 
    int x = 0; 
    for (; x < i.length - 1; x++) { 
     i[x] = i[x + 1]; 
    } 
    i[x] = t; 
    return i; 
    } 
} 

兩個參數調用,它是一種交換。

它可以如下使用:

int x = 1; 
int y = 2; 
Integer[] yx = Shift.left(x,y); 

或者:

Integer[] yx = {x,y}; 
Shift.left(yx); 

然後

x = yx[0]; 
y = yx[1]; 

注:它自動箱原語。

+0

誘惑你,因爲(一)它並不真正幫助 - 結果是一個數組;原來的x,y仍然沒有交換。(b)交換是一種常見操作,可以編寫自定義函數進行交換,而不是使用這種更通用的移位功能。 – ToolmakerSteve

+1

@ToolmakerSteve您是否注意到已經提供了標準交換以及正確的答案,以標準方式無法實現?所以我的答案不是克隆已經提供的答案,而是另一種「交換」。答案的重點在於提供選擇,而不僅僅是讓每個人反覆反覆地回答相同的答案。所以使用換檔換檔是一種有效的交換方式,並不是已經提供的答案,所以我提交了它。 – nicerobot

+0

我仍然不同意:它在問題的上下文中沒有用處。也許在一些不同的問題。我提出的觀察立場。然而,正如我所說的,我的分歧不夠強烈,不足以讓您的答案失效。 – ToolmakerSteve

53

我覺得這是你可以得到一個簡單的互換最接近的,但它並沒有一個簡單的使用模式:

int swap(int a, int b) { // usage: y = swap(x, x=y); 
    return a; 
} 

y = swap(x, x=y); 

它依賴於一個事實,即x將進入swapy之前被分配到x,然後x返回並分配給y

你可以使它通用和交換任何數量的相同類型的對象:

<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z); 
    return args[0]; 
} 

c = swap(a, a=b, b=c) 
+2

這實際上是一個不錯的主意。 – Sunspawn

+3

我同意,一個好主意,但也很危險......因爲它依賴於調用時的參數分配,所以使用此方法的任何項目遲早都會遇到一個bug。如果我是領導者,不會允許在生產代碼中使用。 –

+2

聰明。太聰明瞭。依賴完全正確地編寫此模式的人。稍後非常不明顯。我也會否決生產中的這樣一段代碼。但我同意這很有趣。如此接近... – ToolmakerSteve

-5
public class Swap1 { 
    public static void main(String[] args){ 
     int x =7; 
     int y = 3; 

     swap(x,y); 

     System.out.println("x = " + x); 
     System.out.println("y = " + y); 
    } 

    public static void swap(int x, int y) { 
     int temp = x; 
     x = y; 
     y = temp; 
    } 
} 
+0

不起作用,參數按值傳遞,不參考,x和y不交換。 – gulchrider

+2

認真,你甚至讀過原來的問題嗎? OP已經有了這個功能,並問爲什麼它沒有工作。你仔細打印出來的值,但顯然沒有真正運行你的代碼,看看這些值是什麼。 – ToolmakerSteve

+0

Java使用按值傳遞方案,這意味着在將程序編譯到swap(x,y)時,它會將新的x,y分配到內存中,因此您正在引用新創建的變量。該步驟完成後,由於它不會出現,它將被收集並消失。因此在swap(x,y)之後不會做任何更改。嘗試使用數組來使其工作。 – CHANist

4

顯然,我沒有足夠的信譽分評論Dansalmo's answer,但它是一個不錯,但錯誤。他的回答實際上是一個K-combinator。

int K(int a, int b) { 
    return a; 
} 

JLS is specific about argument evaluation when passing to methods/ctors/etc。 (這是不是在舊的規格?)

當然,這是一個功能成語,但它已經足夠清楚,以識別它的人。 (如果你不明白你找到的代碼,不要猴子吧!)

y = K(x, x=y); // swap x and y 

的K-組合子是專門爲這種事情而設計的。 AFAIK沒有理由不通過代碼審查。

我的$ 0.02。

+2

既然您有足夠的聲望,請將其轉到評論中。謝謝! –

+0

我同意,請在上面添加您的評論。我當時實際上正在大量學習功能技術,可能在不知道模式的情況下在不知不覺中應用了它們。你也可能會覺得這很有趣。 http://pure-fn.appspot.com/about – dansalmo

2

AFAIS,沒有人提到atomic reference

整數

public void swap(AtomicInteger a, AtomicInteger b){ 
    a.set(b.getAndSet(a.get())); 
} 

字符串

public void swap(AtomicReference<String> a, AtomicReference<String> b){ 
    a.set(b.getAndSet(a.get())); 
} 
+0

你不需要一個原子類型來做到這一點。任何可變持有人類將做。即使是元素或引用的單元素數組。 –

0

試試這個神奇的

public static <T> void swap(T a, T b) { 
    try { 
     Field[] fields = a.getClass().getDeclaredFields(); 
     for (Field field : fields) { 
      field.setAccessible(true); 
      Object temp = field.get(a); 
      field.set(a, field.get(b)); 
      field.set(b, temp); 
     } 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
} 

和測試吧!

System.out.println("a:" + a); 
    System.out.println("b:" + b); 
    swap(a,b); 
    System.out.println("a:" + a); 
    System.out.println("b:" + b);