如何在Java中不使用第三个变量交换两个字符串变量

20

在Java中,如何交换两个字符串变量而不使用第三个变量,即temp变量?

String a = "one"
String b = "two"
String temp = null;
temp = a;
a = b;
b = temp;

但是在这里有第三个变量,我们需要消除第三个变量的使用。


1
你知道变量只是引用,可能会被编译器优化掉吗? - Eran
1
你为什么想要消除第三个变量? - Absurd-Mind
1
使用“特殊”分隔符连接,然后再次拆分。 - Roger
如果你们没有注意到的话,这些变量是字符串。 - Aashray
应该欣赏这个问题,因为它涉及到逻辑。 - commit
显示剩余2条评论
19个回答

36

不使用第三个变量,可以这样做:

String a = "one";
String b = "two";

a = a + b;
b = a.substring(0, (a.length() - b.length()));
a = a.substring(b.length());

System.out.println("a = " + a);
System.out.println("b = " + b);

你可以将第三个语句简化为 a = a.substring(b.length()); - Gaurang Tandon
@GaurangTandon 是的,你说得对。已更新答案。 - Ankur Lathi
2
a+b会创建第三个字符串对象(字符串是不可变的)-最好使用临时引用 - 至少你不会创建对象。 - tapasvi
你甚至可以将其缩短为一行代码, a = b + (b = a).substring(0, 0);。 这仍会为了节省本地变量而创建临时字符串实例,因此它仅是一种有趣的事情,而不是推荐的编码风格,但至少,这些字符串实例比连接操作 a + b 更便宜... - Holger
@tapasvi 实际上,它会创建三个不必要的字符串实例,因为substring操作会生成新的字符串,这些字符串与原始字符串实例相等但不完全相同。 - Holger

12

// 参考自这个答案:https://dev59.com/vXM_5IYBdhLWcg3wdzDz#16826296

在IT技术中,"fork"是指复制一个进程的副本。这个新的进程(子进程)和原始进程(父进程)在某些方面是相同的,但也有一些不同之处。子进程可以继承父进程的资源,如文件描述符、内存等,并且可以执行与父进程不同的代码路径。在Unix系统中,fork()函数用于创建子进程。
String returnFirst(String x, String y) {
    return x;
}

String a = "one"
String b = "two"
a = returnFirst(b, b = a); // If this is confusing try reading as a=b; b=a;

这段代码有效的原因是Java语言保证了所有参数从左到右进行求值(Java语言规范,Java SE 7版,第15.12.4.2节),这与其他一些语言不同,其求值顺序未定义,因此执行顺序如下:
  1. 评估b的原始值以便作为函数的第一个参数传递
  2. 评估表达式b = a,并将结果(b的新值)作为第二个参数传递给函数
  3. 函数执行,返回b的原始值并忽略其新值
  4. 将结果分配给a
  5. 现在值已经交换,您不需要声明temp。参数x充当temp,但看起来更干净,因为您只需定义一次函数即可在任何地方使用它。

1
要求是不使用第三个变量进行交换。 通过创建一个函数returnFirst(String x, String y),你会创建两个新变量,因为它是按值传递,而不是按引用传递。 - shanraisshan
主要优点是您不会在本地作用域中添加额外的变量。一旦函数被创建,您可以多次使用它,而不必担心“temp”变量的负担。尽管在运行时仍会有额外的变量,但它有助于编写和阅读程序的程序员。 - marcus

6
String a="one";
String b="two";

a = a.concat("#" + b);
b = a.split("#")[0];
a = a.split("#")[1];

只要您的字符串中不包含#字符,这种方法就可以工作。您可以随意使用其他字符代替它。您可以使用可能的Unicode字符,例如"\u001E"代替#。

还不错,我的想法也是这样。请确保使用不在字符串中的分隔符。 - Roger
1
如果任何字符串包含 '#' 值,那么怎么办? - bNd
正如我明确指出的那样,“只要您的字符串不包含#字符,这将起作用”。因此,回答@BMT的问题,这段代码在那种情况下不起作用。 - Husman
@Husman,你的回答不起作用吗?那你为什么要回答呢? - xehpuk
@xehpuk 显然英语不是你的母语。只要你的字符串不包含#字符,它就可以工作。如果你只是处理普通单词,那么这是一个可行的答案。你可以用任何其他ASCII字符替换#。在发表无用的评论之前,请先阅读答案和评论。 - Husman
显示剩余4条评论

2
public class SwapStringVariable {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String a = "test";
        String b = "paper";

        a = a + b;
        b = a.substring(0, a.length()  - b.length());
        a = a.substring(b.length(), a.length());

        System.out.println(a + " " + b);


    }

}

1
String str1 = "first";
String str2 = "second";

str1 = str2+str1;
str2 = str1.substring(str2.length(),str1.length());
str1 = str1.substring(0,(str1.length() - str2.length()));

System.out.println(str1);
System.out.println(str2);

请问您能否解释一下代码如何实现所需的功能? - Phani
我觉得这很容易理解..!你能告诉我哪一行你没看懂吗? - Nirav Dhinoja

1
String name = "george";
String name2 = "mark";
System.out.println(name+" "+name2);
System.out.println(name.substring(name.length()) + name2 +  " "+ name );

在这里,substring()方法返回空字符串。因此,可以添加名称。


1
最简单的方法如下所示:

String a = "one";
String b = "two";
System.out.println("Before swap: " a + " " + b);
int len = a.length();
a = a + b;
b = a.substring(0, len);
a = a.substring(len);
System.out.println("After swap: " a + " " + b);

2
不使用第三个变量!(len) - Roger
@Rogier 在问题本身中明确提到第三个变量是临时变量。'........第三个变量,即临时变量' - Praveen P Moolekandathil
1
所以你把原帖的第三个变量删掉了,然后加入了自己的一个。不错。 - Husman

0

包 com.core;

公共类 SwappingNoTemp {

public static void main(String[] args) {

    String a = "java";
    String b = "c";

    a = a + b;

    b = a.substring(0, a.length() - b.length());
    a = a.substring(b.length());

    System.out.println("swapping is a.." + a);
    System.out.println("swapping  is b.." + b);

}

}


0

字符串相关方法1:

public class SwapWithoutThirdVar{  
public static void main (String args[]){    
 String s1 ="one";
 String s2 ="two";
 s1= s1+s2;
 s2 = s1.substring(0,(s1.length()-s2.length()));
 s1 = s1.substring(s2.length()); 
 System.out.println("s1 == "+ s1);
 System.out.println("s2 == "+ s2);

}
}

方法二:

public class SwapWithoutThirdVar
{
public static void main (String[] args) throws java.lang.Exception
 {
 String s1 = "one";            
 String s2 ="two";          
 s1=s2+s1;
 s2=s1.replace(s2,"");
 s1=s1.replace(s2,"");         
 System.out.println("S1 : "+s1); 
 System.out.println("S2 : "+s2);
  }
}

针对整数

公共类 SwapWithoutThirdVar {

public static void main(String a[]){
    int x = 10;
    int y = 20;       
    x = x+y;
    y=x-y;
    x=x-y;
    System.out.println("After swap:");
    System.out.println("x value: "+x);
    System.out.println("y value: "+y);
}
}

0

你可以这样做。

public static void main(String[] args) {
        // TODO Auto-generated method stub

        String a = "one";
        String b = "two";

        System.out.println(a);
        System.out.println(b);

        a = a+b;
        b = "";

        System.out.println("*************");
         b = a.substring(0, 3);
         a = a.substring(3, 6);

         System.out.println(a);
         System.out.println(b);

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接