交换原语的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;
}

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

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的先前内容。

您无法创建方法交换,因此在调用
交换(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);
然后


注意:它会自动装箱原语。

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

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)

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

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。

显然,我没有足够的声誉点来评论,但这是一个不错的声誉点,尽管名字不正确。他的答案实际上是一个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());
}
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();
    }
}
试试这个魔术

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₀.

对于整数类型,您可以

a ^= b;
b ^= a;
a ^= b;
使用位异或运算符
^
。与所有其他建议一样