【问题标题】:How to write a basic swap function in Java [duplicate]如何用Java编写基本的交换函数[重复]
【发布时间】:2011-04-07 04:11:25
【问题描述】:

我是 Java 新手。如何编写以下 C 代码的 java 等价物。

void Swap(int *p, int *q)
{
   int temp;
   temp = *p;
   *p = *q;
   *q = temp;
} 

【问题讨论】:

  • 我不会简单地给出一个交换方法,而是给你this article。它解释了如何制作交换方法,还解释了如何不制作它,以及为什么它不可能以您期望的形式出现,因为 Java 只是按值传递(与 C/C++ 不同)
  • 错误答案.. java 不仅是按值传递.. 当您传递非本机值时,您正在传递一个指针。如果你必须更新它,它是一个指针。 javadude.com/articles/passbyvalue.htm
  • 您正在传递对对象的引用 - 是的,但是引用被复制了。 “按值传递引用”可能是一个更好的描述。不能更改传递的引用,只能更改目标对象
  • 我认为 method 是最接近 Java 中的交换函数的。
  • 我发现这篇文章试图弄清楚同样的事情。 link

标签: java swap


【解决方案1】:

这里有一个技巧:

public static int getItself(int itself, int dummy)
{
    return itself;
}

public static void main(String[] args)
{
    int a = 10;
    int b = 20;

    a = getItself(b, b = a);
}

【讨论】:

  • 您会雇用一个会编写晦涩难懂的代码的人吗?也许他们会解释为什么他们永远不会在生产代码中真正这样做
  • 加一是为了技巧,减一是因为如果没有一些好的解释,它就不能在生产中广泛使用。它不能包含在单独的方法中,可以吗?
  • 查看这里stackoverflow.com/questions/1363186/… 了解它是如何工作的。
  • 谢谢你。很长时间没有将 Java 作为我的主要语言,我误解了部分语法。我认为 Java 对 C/C++ 所做的一项改变是赋值不是表达式。事实上,变化在于 Java 引入了一个正确的布尔类型,它不能与整数互换使用,因此您不能在不返回布尔值的 if 语句中使用赋值。赋值返回赋值中涉及的任何类型,它们返回赋值表达式的右侧。
  • @GabrielŠčerbák 我要提醒的是,如果使用它的员工可以以一种很明显正在执行交换的方式表达它,那么他们应该受到称赞。该解决方案的缺点是首先尝试在 Java 中创建交换功能。如果不先将它们填充到对象或数组中,您实际上无法交换基本类型。 ://
【解决方案2】:

对两个整数进行排序

简短的回答是:你不能那样做,java 没有指针。

但是你可以做一些类似的事情:

public void swap(AtomicInteger a, AtomicInteger b){
    // look mom, no tmp variables needed
    a.set(b.getAndSet(a.get()));
}

您可以对所有类型的容器对象(如集合和数组或具有 int 属性的自定义对象)执行此操作,但不能使用基元及其包装器(因为它们都是不可变的)。但我想,让它成为单线的唯一方法是使用 AtomicInteger。

顺便说一句:如果你的数据恰好是一个列表,更好的交换方法是使用Collections.swap(List, int, int)

Swaps the elements at the specified positions in the specified list.
(If the specified positions are equal, invoking this method leaves
the list unchanged.)

Parameters:
    list - The list in which to swap elements.
    i - the index of one element to be swapped.
    j - the index of the other element to be swapped. 

对 int[] 数组进行排序

显然,真正的目标是对整数数组进行排序。 那是与Arrays.sort(int[]) 的单行代码:

int[] arr = {2,3,1,378,19,25};
Arrays.sort(arr);

检查输出:

System.out.println(Arrays.toString(arr));
// [1, 2, 3, 19, 25, 378]

这是一个简单的辅助函数,用于交换整数数组中的两个位置:

public static void swap(final int[] arr, final int pos1, final int pos2){
    final int temp = arr[pos1];
    arr[pos1] = arr[pos2];
    arr[pos2] = temp;
}

【讨论】:

  • 因为我在做一些排序算法,所以我有一个整数数组。在调用 swap 之前,我是否需要将普通整数类型转换为 AtomicInteger?
  • 如果要对整数数组进行排序,请使用 Arrays.sort() download.oracle.com/javase/6/docs/api/java/util/…
  • 顺便说一句,没有办法将原始类型强制转换为对象,但 AtomicInteger 有一个带有 int 的构造函数
  • @Melinda:Arrays.sort 是答案,但如果你想交换两个简单的值,请遵循 ol'good 方法:int aux = b; b = a; a = aux;
  • 但是人们可能并不总是想只对整数进行排序,更不用说只对基元进行排序了。真正的“将始终在 Java 中工作”的答案是您使用 setter 和 getter 的交换方法。它对我有用,对我帮助很大,谢谢。
【解决方案3】:

这是一种使用按位XOR(^)运算符在java中在一行中交换两个变量的方法。

class Swap
{
   public static void main (String[] args)
   {
      int x = 5, y = 10;
      x = x ^ y ^ (y = x);
      System.out.println("New values of x and y are "+ x + ", " + y);
   }
} 

输出:

x 和 y 的新值为 10、5

【讨论】:

  • 因为这不能回答问题。问题是关于一个独立函数,它可以将两个变量作为参数并交换它们。
【解决方案4】:

将此单线用于任何原始数字类,包括doublefloat

a += (b - (b = a));

例如:

double a = 1.41;
double b = 0;
a += (b - (b = a));
System.out.println("a = " + a + ", b = " + b);

输出为a = 0.0, b = 1.41

【讨论】:

    【解决方案5】:

    Java 中没有指针。但是,每个“包含”对象的变量都是对该对象的引用。要拥有输出参数,您必须使用对象。 在你的情况下,整数对象。

    因此,您必须创建一个包含整数的对象,然后更改该整数。你不能使用 Integer 类,因为它是不可变的(即它的值不能改变)。

    另一种方法是让方法返回一个数组或一对整数。

    【讨论】:

    • 整数对象是不可变的,所以这也行不通。
    • 整数无济于事,它们是不可变的。你需要一个容器,要么是 AtomicInteger(见我的回答),要么是 1 元素列表或数组或任何类似的东西
    • 同样,整数对象将按值传递。这也行不通。 javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
    • @Lunivore: 不,Integer 对象不是按值传递的。他们根本没有通过。 引用 Integer 对象 将按值传递。 Java 中只能传递引用和原始值,不能传递对象!
    • 对不起。我很懒惰,你的描述要准确得多。在我的辩护中,URL 很好地解释了它,即使对于不可变的对象也是如此。
    【解决方案6】:

    在这种情况下,有一种使用带有一个元素的数组的快速而肮脏的解决方案:

    public void swap(int[] a, int[] b) {
      int temp = a[0];
      a[0] = b[0];
      b[0] = temp;
    }
    

    当然,您的代码也必须使用这些数组,这很不方便。如果您想从内部类修改局部最终变量,则数组技巧会更有用:

    public void test() {
      final int[] a = int[]{ 42 };  
      new Thread(new Runnable(){ public void run(){ a[0] += 10; }}).start();
      while(a[0] == 42) {
        System.out.println("waiting...");   
      }
      System.out.println(a[0]);   
    } 
    

    【讨论】:

      【解决方案7】:

      强大的 IntHolder 呢?我只是喜欢任何名称中带有 omg 的包!

      import org.omg.CORBA.IntHolder;
      
      IntHolder a = new IntHolder(p);
      IntHolder b = new IntHolder(q);
      
      swap(a, b);
      
      p = a.value;
      q = b.value;
      
      void swap(IntHolder a, IntHolder b) {
          int temp = a.value;
          a.value = b.value;
          b.value = temp;
      }
      

      【讨论】:

        【解决方案8】:

        片段 1

        public int[] swap1(int[] values) {
          if (values == null || values.length != 2)
            throw new IllegalArgumentException("parameter must be an array of size 2");
          int temp = values[0];
          values[0]=values[1];
          values[1]=temp;
          return values;
        }
        

        片段 2

        public Point swap2(java.awt.Point p) {
          if (p == null)
            throw new NullPointerException();
          int temp = p.x;
          p.x = p.y;
          p.y = temp;
          return p;
        }
        

        用法:

        int[] values = swap1(new int[]{x,y});
        x = values[0];
        y = values[1];
        
        Point p = swap2(new Point(x,y));
        x = p.x;
        y = p.y;
        

        【讨论】:

        • 是的。甚至很有趣。但它比使用临时变量的内联交换更多的编码。也许最好指出如果程序员愿意在某个对象中携带这两个值,那么它们可以在该对象中交换。但是,我想不出在实践中有任何帮助的算法。
        【解决方案9】:

        Java 使用 按值传递。无法使用方法交换两个原语或对象

        虽然可以交换整数数组中的两个元素。

        【讨论】:

        • 不可能通过将两个东西作为参数传递给方法来交换它们——不仅仅是原语。
        • @Lunivore 我认为对象是通过引用传递的。那么,在那种情况下,你为什么不能交换他们的参考资料?
        • @Cristian:不正确:java 对象是按值传递的引用。这就是区别
        • @seanizer 感谢您的澄清!
        • C 也使用 pass-by-value,只有 C++ 有 pass-by-reference。即使在给出的示例中,它也传递了两个指针的值。这就是为什么没有传递引用与 Java 中的这种限制没有任何关系。
        【解决方案10】:

        你不能在 Java 中使用引用,所以交换函数是不可能的,但你可以在每次使用交换操作时使用以下代码 sn-p:

        T t = p
        p = q
        q = t
        

        其中 T 是 p 和 q 的类型

        但是,可以通过重写属性来交换可变对象:

        void swap(Point a, Point b) {
          int tx = a.x, ty = a.y;
          a.x = b.x; a.y = b.y;
          b.x = t.x; b.y = t.y;
        }
        

        【讨论】:

        • 这是一个有用的观察结果。
        【解决方案11】:

        你必须内联。但是你真的不需要在 Java 中进行这种交换。

        【讨论】:

        • 不知道为什么这被否决了,因为它实际上是准确的。如果你有这两个值并且你想交换它们,你可以内联方法并且它工作得很好 - 但我同意,我真的不明白为什么你在 Java 中也需要它。
        • 谢谢。我也很惊讶。它可能过于简洁,但代码表明了类似 C 的编码风格,这完全不是 Java 做事的方式。
        • 像“你真的不需要在 Java 中进行这种交换”这样笼统的声明值得反对。交换作为一个编程概念的实用性是无可争辩的。有许多算法,其中swap 是关键步骤。如果 Bart 不希望被否决,他需要提供一个替代解决方案,以解决传统上在算法中使用 swap 的情况(正如其他几个答案所做的那样,但不完整)。
        【解决方案12】:

        您的交换函数本质上是在更改两块内存中的值。任何引用这些内存位的东西现在都会得到不同的值。

        在 Java 中并没有真正的指针,所以这是行不通的。相反,引用保存在对象上,您只能更改对象内部的内容。如果您需要在两个地方引用一个对象,以便您可以在系统中传递相同的值并让事物对它们的变化做出反应,请尝试使用the repository patterndependency injection 之类的方法。

        我们只能猜测您为什么需要在 C 中使用此代码。我能给出的唯一建议是考虑对您想要实现的对象的更改,最好在实际对象上添加一个方法,而不是拉取它们的内部出,并改为调用该方法。如果这对您没有帮助,请尝试发布调用代码,因为我们可能会很好地了解如何以 Java 风格解决实际问题。

        【讨论】:

          【解决方案13】:

          Java 是按值传递的。因此,您所说的swap 是不可能的。但是您可以交换两个对象的内容,也可以内联。

          【讨论】:

            【解决方案14】:

            您可以使用或不使用临时变量来交换变量。

            这是一篇文章,提供了多种方法来交换没有临时变量的数字:

            http://topjavatutorial.com/java/java-programs/swap-two-numbers-without-a-temporary-variable-in-java/

            【讨论】:

              【解决方案15】:

              您可以轻松地自己编写一个。

              给定:

              int array[]={1,2};
              

              你会的:

              int temp=array[0];
              array[0]=array[1];
              array[1]=temp;
              

              你就完成了。 3 行代码。

              【讨论】:

              • 这不起作用。您需要更仔细地阅读问题并阅读其他一些答案。
              • 尽量小心@AndrewMartin。因为我工作没有任何问题。
              • 你错过了问题的重点。 OP 正在询问如何在 类似 C 的方法中进行交换。 Java 不能 这样做,因为它是按值传递的。如果在方法中进行了交换,则不能存储(除非返回值)。如果将两个值传递给一个方法并执行了您的代码,则它不会将结果存储在该方法之外。阅读反对的问题和其他一些答案。
              【解决方案16】:

              使用 pointer 进行交换在 java 中是不可能的。 不过,您可以通过传递包含两个对象的数组来实现交换。

              代码如下:

              public class Swap {
                  public static void swap(String [] a){
                      String temp;
                      temp = a[0];
                      a[0] = a[1];
                      a[1] = temp;
                  }
                  public static void main(String [] args){
                      String [] foo = new String[2];
                      foo[0] = "str1";
                      foo[1] = "str2";
                      swap(foo);
                      System.out.println("First value: "+ foo[0]);
                      System.out.println("Second value: "+ foo[1]);
                  }
              }
              

              输出:

              First value: str2
              Second value: str1
              

              【讨论】:

                【解决方案17】:
                public class swaptemp {
                    public static void main(String[] args) {
                        String s1="10";
                        String s2="20";
                        String temp;
                        System.out.println(s1);
                        System.out.println(s2);
                
                        temp=Integer.toString(Integer.parseInt(s1));
                        s1=Integer.toString(Integer.parseInt(s2));
                        s2=Integer.toString(Integer.parseInt(temp));
                
                        System.out.println(s1);
                        System.out.println(s2);
                    }
                }
                

                【讨论】:

                • 请尝试在您的代码中包含 cmets/解释,以帮助其他人更好地理解它。
                【解决方案18】:
                //here is also another answer:
                class SwapDemo{
                    static int a=1, b=2 ;
                    public static void main(String [] args){
                        Swap swp = new Swap();
                        swp.swaps(x,y);
                        System.out.println( " a (was 1)now is " + a + " b (was 2) now is " + b);
                    }
                }
                class Swap{
                    void swaps(int c, int d){
                            SwapDemo f = new SwapDemo();
                            f.a = c;
                            f.a = d;
                        }
                }
                

                【讨论】:

                • 这看起来有点晕,但它根本不是 OOP。希望这也会有所帮助。
                • x 和 y 未定义,这不是交换传递的变量。
                • 这不是问题的答案。这不是计算机科学中“交换两个变量”的含义。相反,这是“更改两个成员的值”。甚至没有关闭。
                【解决方案19】:
                  class Swap2Values{
                    public static void main(String[] args){
                       int a = 20, b = 10;
                
                       //before swaping
                       System.out.print("Before Swapping the values of a and b are: a = "+a+", b = "+b);
                
                       //swapping
                       a = a + b;
                       b = a - b;
                       a = a - b;
                
                       //after swapping
                      System.out.print("After Swapping the values of a and b are: a = "+a+", b = "+b);
                    }
                  }
                

                【讨论】:

                • 问题是如何在 java 中编写交换函数而不是如何在 java 中进行交换
                猜你喜欢
                • 1970-01-01
                • 2022-01-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-09-16
                • 2015-02-16
                • 2019-05-10
                • 1970-01-01
                相关资源
                最近更新 更多