交换原语的Java方法

交换原语的Java方法,java,swap,Java,Swap,如果没有可以通过引用传递的方法,我如何在java中实现swap函数?谁能给我一个密码吗 swap(int a, int b) { int temp = a; a = b; b = temp; } 但是这些变化不会反映出来,因为java是按值传递参数的。这取决于您想做什么。这段代码交换数组的两个元素 void swap(int i, int j, int[] arr) { int t = arr[i]; arr[i] = arr[j]; arr[j] =

如果没有可以通过引用传递的方法,我如何在java中实现swap函数?谁能给我一个密码吗

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

但是这些变化不会反映出来,因为java是按值传递参数的。

这取决于您想做什么。这段代码交换数组的两个元素

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);
}
类似的内容交换两个
位集的内容(使用):

类似这样的东西交换一些
类的
x
y
字段:

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

无法创建方法交换,因此在调用
swap(x,y)
后,x和y的值将被交换。您可以通过交换可变类的内容,为它们创建这样一个方法,但这不会改变它们的对象标识,您也不能为此定义一个通用方法

但是,如果需要的话,可以编写一个方法来交换数组或列表中的两个项


例如,您可以创建一个包含两个列表的交换方法,执行该方法后,列表x将具有列表y的先前内容,列表y将具有列表x的先前内容。

我可能会执行以下操作。当然,由于集合类的丰富,我无法想象在任何实际代码中都需要使用它

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;
  }
}
或者:

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


注意:它自动装箱原语。

我认为这是最接近简单交换的方法,但它没有简单的使用模式:

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

y = swap(x, x=y);
它依赖于这样一个事实,
x
将在
y
分配给
x
之前进入
swap
,然后
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)
T交换(T…args){//用法:z=swap(a,a=b,b=c,…y=z);
返回参数[0];
}
c=互换(a,a=b,b=c)

显然,我没有足够的声誉点来评论,但这是一个不错的声誉点,尽管名字不正确。他的答案实际上是一个K-组合子

int K( int a, int b ) {
    return a;
}
这个。(在旧规格中不是这样吗?)

诚然,这是一个功能性的习语,但对认识它的人来说已经足够清楚了。(如果您不理解找到的代码,请不要弄乱它!)

K-combinator是专门为这种事情设计的。好吧,没有理由不通过代码审查

我的$0.02。

是AFAIS,没人提到

整数

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()));
}
公共无效交换(原子参考a、原子参考b){
a、 set(b.getAndSet(a.get());
}
试试这个魔术

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();
    }
}

对于整数类型,可以执行以下操作

a ^= b;
b ^= a;
a ^= b;
使用逐位异或运算符
^
。正如所有其他建议一样,您可能不应该在生产代码中使用它

出于我不知道的原因,单行版本
a^=b^=a^=b
不起作用(可能我的Java编译器有一个bug)。这一行代码在我尝试过的所有编译器中都能在C语言中运行。但是,两行版本可以工作:

a ^= b ^= a;
b ^= a;
以及

b ^= a;
a ^= b ^= a;

证明它有效的证据是:让₀ b₀ 是
a
b
的初始值。在第一行之后,
a
是一个₁ = A.₀ 异或b₀; 在第二行之后,
b
是b₁ = B₀ 异或a₁ = B₀ 异或(a)₀ 异或b₀) = A.₀. 在第三行之后,
a
是一个₂ = A.₁ 异或b₁ = A.₁ 异或(b)₀ 异或a₁) = B₀.

如果您想获得帮助,您必须更明确地说明您试图完成的任务。查看本文:Java中的所有参数都是按值传递的。@gurukulki:这不会改变任何事情。如果Integer有一个
setValue
方法,您可以使用该方法而不是赋值,这将达到预期的效果(除非您还希望更改对象标识),但既然没有,使用Integer也没有什么帮助。Chk this out。有关按引用交换的详细信息。Chk this out。有关按引用交换的详细信息。数组是否按引用传递?否。Java中的所有内容都是按值传递的,包括对Java中数组的引用。在这种情况下,数组与任何其他对象都没有区别。@D.J:数组(与所有对象一样)是引用类型。这意味着对方法内部对象所做的任何更改都将在外部可见(也意味着将对象传递给方法不会复制对象的内容,因此传递1M元素数组不会复制1M对象)。但是,重新分配引用数组的变量在外部将不可见(这意味着如果在方法内部执行类似于
arr1=arr2
的操作,这将不会对外部产生任何可见的影响)。您可以创建一个名为
y=swap(x,x=y)的
交换x和y。这实际上是一个不错的主意。我同意,这是一个不错的主意,但也很危险……因为它依赖于调用时的参数分配,任何使用此方法的项目迟早会因为它而遇到错误。如果我是lead,就不允许在生产代码中使用此方法。聪明。太聪明。依赖于编写此模式的人n完全正确。非常不明显,稍后阅读。我也会在生产中否决这样一段代码。但我同意它非常有趣。如此接近……因为它依赖于调用时的参数赋值,所以人们担心可能在某个地方,不知何故,Java的某些实现可能会出错。另外,正如我在描述中所指出的,使用模式并不简单。@您还应该注意,方法名
swap
是一个谎言,它没有做它应该做的事情。这个想法可能很好,但这段代码不应该通过任何代码审查。试图否决您,因为(a)它并没有真正的帮助-结果是一个数组;原始的x,y仍然没有交换。(b)交换是一个非常常见的操作,人们会编写一个自定义函数来交换,而不是使用这个更通用的移位函数。@ToolmakerSteve您注意到了吗
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);
a ^= b;
b ^= a;
a ^= b;
a ^= b ^= a;
b ^= a;
b ^= a;
a ^= b ^= a;