交换原语的Java方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2393906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:56:57  来源:igfitidea点击:

Java method to swap primitives

javaswap

提问by higherDefender

how do I make my swap function in java if there is no method by which we can pass by reference? Could somebody give me a code?

如果没有可以通过引用传递的方法,我该如何在 java 中创建我的交换函数?有人可以给我一个代码吗?

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

But the changes wont be reflected back since java passes parameters by value.

但是由于java按值传递参数,因此不会反映更改。

采纳答案by sepp2k

You can't create a method swap, so that after calling swap(x,y)the values of x and y will be swapped. You could create such a method for mutable classes by swapping their contents1, but this would not change their object identity and you could not define a general method for this.

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

You can however write a method that swaps two items in an array or list if that's what you want.

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

1 For example you could create a swap method that takes two lists and after executing the method, list x will have the previous contents of list y and list y will have the previous contents of list x.

1 例如,您可以创建一个接受两个列表的交换方法,在执行该方法后,列表 x 将拥有列表 y 的先前内容,而列表 y 将拥有列表 x 的先前内容。

回答by polygenelubricants

It depends on what you want to do. This code swaps two elements of an array.

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

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

Something like this swaps the content of two int[]of equal length.

像这样的东西交换两个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);
}

Something like this swaps the content of two BitSet(using the XOR swap algorithm):

像这样交换两个的内容BitSet(使用XOR 交换算法):

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

Something like this swaps the xand yfields of some Pointclass:

这样的事情交换了某些类的xy字段Point

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

回答by nicerobot

I might do something like the following. Of course, with the wealth of Collection classes, i can't imagine ever needing to use this in any practical code.

我可能会做类似以下的事情。当然,有了丰富的 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;
  }
}

Called with two arguments, it's a swap.

用两个参数调用,这是一个交换。

It can be used as follows:

它可以按如下方式使用:

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

Alternatively:

或者:

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

Then

然后

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

Note: it auto-boxes primitives.

注意:它自动装箱基元。

回答by dansalmo

I think this is the closest you can get to a simple swap, but it does not have a straightforward usage pattern:

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

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

y = swap(x, x=y);

It relies on the fact that xwill pass into swapbefore yis assigned to x, then xis returned and assigned to y.

它依赖于x将传入swap之前的事实y分配给x,然后x返回并分配给y

You can make it generic and swap any number of objects of the same type:

您可以使其通用并交换任意数量的相同类型的对象:

<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)

回答by Dúthomhas

Apparently I don't have enough reputation points to commenton Dansalmo's answer, but it is a good one, though mis-named. His answer is actually a K-combinator.

显然,我没有足够的信誉分评论Dansalmo的答案,但它是一个很好的,虽然错命名。他的答案实际上是一个K-combinator。

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

The JLS is specific about argument evaluation when passing to methods/ctors/etc. (Was this not so in older specs?)

JLS是关于特定参数的评价传递给方法/构建函数/等时。(在旧规范中不是这样吗?)

Granted, this is a functionalidiom, but it is clear enough to those who recognize it. (If you don't understand code you find, don't mess with it!)

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

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

The K-combinator is specifically designed for this kind of thing. AFAIK there's no reason it shouldn't pass a code review.

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

My $0.02.

我的 0.02 美元。

回答by snr

AFAIS, no one mentions of atomic reference.

AFAIS,没有人提到atomic reference

Integer

整数

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

String

细绳

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

回答by Mark Hetherington

Try this magic

试试这个魔法

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

And test it!

并测试它!

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

回答by Bolpat

For integer types, you can do

对于整数类型,你可以这样做

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

using the bit-wise xor operator ^. As all the other suggestions, you probably shouldn't use it in production code.

使用按位异或运算符^。与所有其他建议一样,您可能不应该在生产代码中使用它。

For a reason I don't know, the single line version a ^= b ^= a ^= bdoesn't work (maybe my Java compiler has a bug). The single line worked in C with all compilers I tried. However, two-line versions work:

出于我不知道的原因,单行版本a ^= b ^= a ^= b不起作用(也许我的 Java 编译器有错误)。单行在 C 中与我尝试过的所有编译器一起工作。但是,两行版本有效:

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

as well as

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

A proof that it works: Let a? and b? be the initial values for aand b. After the first line, ais a? = a? xor b?; after the second line, bis b? = b? xor a? = b? xor (a? xor b?) = a?. After the third line, ais a? = a? xor b? = a? xor (b? xor a?) = b?.

证明它有效:让a?和 b? 是初始值ab。在第一行之后,a是?= 一个?异或 b?; 在第二行之后,b是 b?= 乙?异或? = 乙?xor (a? xor b?) = a?。在第三行之后,a是一个?= 一个?异或 b? = 一个?xor (b? xor a?) = b?。