不使用临时变量交换字符串值

4

我知道溢出、性能下降等问题,但我需要在没有任何临时变量的情况下交换两个字符串值。我了解构造函数,并找到了一些有效的方法,但无法理解其中一个。

String a = "abc";
String b = "def";

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

System.out.printf("A: %s, B: %s", a, b);

输出结果显示明显的值已经被交换了。当我看到这个结果时,似乎与优先级操作有关,但我无法在脑海中理清它。请问是否有人能够解释一下发生了什么?


你想要确切了解什么? - Sunny
你的意思是不使用任何临时变量吗?你不想看到使用临时变量吗?因为我相信总会有一个隐式存储了某个临时变量。 - skiwi
@skiwi 当然是隐式的,特别是当处理不可变对象时。 - Chris
4个回答

7
基本上,您可以考虑交换操作。
b = a + (a = b).substring(0, 0);

as

b = "abc" + (a = "def").substring(0, 0);

在这第一步中,我只是将变量用它们的值进行替换(括号内的 a 除外,因为这是一个赋值而不是读取)。现在 a 等于 "def",因此 b 是:
b = "abc" + "def".substring(0, 0);

在这一步中,我用它的值替换了括号。现在很明显:
b = "abc";

由于方法.substring(0, 0)返回一个空字符串。

因此,交换已完成。


1
这可能甚至不那么低效,因为唯一创建的临时字符串长度为零。(我假设附加一个零长度的字符串只返回输入)。 - Thilo
1
假设将一个零长度的字符串附加到输入中,这只会返回输入。好吧,可能不是这样的,因为该过程似乎必须涉及一个StringBuilder,它必须复制一些东西。 - Thilo
1
嗯,这就是我在寻找的答案。谢谢@EnneCH的解释。我知道这段代码不是常规的编码风格,也不是良好的实践,但有时面试官会要求这样的东西。 - Chris

0
假设a和b都是字符串变量:
a = (a+b).Substring((b=a).Length);

0

如果你需要问这里发生了什么,那么你应该认真考虑在你的代码中使用这样的结构。

因为在Java中表达式是从左到右进行评估(参见这里 -“评估顺序”部分)。

以下是b = a + (a = b).substring(0,0)情况下的逐步操作。

  • 用其值填充变量 a:

    b = "abc" + (a = b).substring(0, 0);

  • 用其值填充变量 b:

    b = "abc" + (a = "def").substring(0, 0);

  • 由于字符串连接(+)的第一个属性已经被评估,因此请评估以重新分配 "def"a 开头的第二个属性。

    b = "abc" + "def".substring(0, 0); //现在 a = "def"

  • "def" 运行 substring

    b = "abc" + ""

  • 连接

    b = "abc"

  • 重新分配给 b,现在 b = "abc"(如前所示,a 已被重新分配为 "def")。


0
公开类交换{ public static void main(String are[]) {
    //Swapping two Integer without temp variable 
    int a=10;
    int b=20;
    a=a+b;
    b=a-b;
    a=a-b;
    System.out.println(a+" "+b);
    
    //Swapping two string character with temp variable.
    String str1="Good";
    int as=str1.length();
    String str2="Morning";
    str1=str1+str2;
    str2=str1.substring(0, as);
    str1=str1.substring(as);
    System.out.println(str1+" "+str2);
}

}


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