在 Java 中交换两个字符串,方法是将它们传递给实用函数,但不返回对象或使用包装类
我正在尝试在 Java 中交换两个字符串。我从来没有真正理解“字符串是不可变的”。我在理论上理解它,但在实践中我从未遇到过。
另外,由于 String 是 Java 中的对象而不是原始类型,所以我不明白为什么下面的代码会打印相同的结果两次,而不是互换单词!
public static void main(String[] args)
{
String s1 = "Hello";
String s2 = "World";
System.out.println(s1 + " " + s2);
Swap(s1, s2);
System.out.println(s1 + " " + s2);
}
public static void Swap(String s1, String s2)
{
String temp = s1;
s1 = s2;
s2 = temp;
}
我希望它打印
Hello World
World Hello
但它正在打印
Hello World
Hello World
我认为 s1 和 s2 是引用,因此引用应该交换,新的引用应该分别指向另一个。我哪里出错了?
I am trying to swap two strings in Java. I never really understood "strings are immutable". I understand it in theory, but I never came across it in practice.
Also, since String is an object in Java and not a primitive type, I don't understand why the following code prints the same result twice, instead of interchanging the words!
public static void main(String[] args)
{
String s1 = "Hello";
String s2 = "World";
System.out.println(s1 + " " + s2);
Swap(s1, s2);
System.out.println(s1 + " " + s2);
}
public static void Swap(String s1, String s2)
{
String temp = s1;
s1 = s2;
s2 = temp;
}
I want it to print
Hello World
World Hello
But it is printing
Hello World
Hello World
I thought s1 and s2 are references and hence the references should be swapped and the new ones should point to the other one respectively. Where am I going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
是的。在本地内部
交换
中,这正是发生的情况。但是,
s1
和s2
是传递到函数中的引用的副本,因此效果仍然是本地的。请注意,复制的不是字符串(因为String
是引用类型)。但引用被复制了。…并且由于参数引用总是在Java中复制,因此根据您的规范编写
交换
函数很简单,是不可能的。如果您无法理解其中的区别,请考虑以下情况:您想给朋友写一封信,因此您将她的邮政地址从地址簿复制到信封上。通过这个过程,你当然没有复制她的家(复制整个房子在实践中有点困难)——你只是复制了地址。
嗯,地址指的是她的家,因此它与 Java 引用完全相同。
Yes. Locally inside
swap
, this is exactly what happens.However,
s1
ands2
are copies of the references passed into the function, so the effect remains local. Note that it’s not the strings that are copied (sinceString
is a reference type). But the references are copied.… and since parameter references are always copied in Java, writing a
swap
function according to your specifications is, quite simply, not possible.If you have problems understanding the difference, consider this: you want to write a letter to a friend so you copy her postal address from your address book onto an envelope. By this process, you certainly didn’t copy her home (copying a whole house is a bit difficult in practice) – you only copied the address.
Well, an address refers to her home so it’s exactly like a Java reference.
下面的代码是NoGo,永远不要实现这个反模式,永远不要改变不可变对象上的私有最终内部结构。不要责怪我展示了这个 hack,责怪 Oracle 的 jvm 没有禁止它。
但是,如果有一天您发现一些代码可以正常工作:
交换的实现可能如下所示:(请自行承担风险,我警告过您!)
The following code is a NoGo, never implement this anti pattern, never ever ever ever change private final internals on immutable objects. Don't blame me for showing this hack, blame Oracle's jvm for not disallowing it.
But, if one day you find some code where this works:
the implementation of
swap
could look like this: (read on your own risk, I warned you!)基本上,您无法在 Java 中实现
swap
方法。不能这样做的原因是 Java 参数具有按值传递参数语义。因此,当您的
swap
方法将s2
分配给s1
等时,它完全在本地变量上运行< code>s1 和s2
,而不是调用方法main
s1 和s2
变量>。相比之下,如果您要在 C 中实现
swap
方法,它将看起来像这样:您可以这样调用它:
请注意,我们实际上传递的是“指向 char 的指针”的地址“ 多变的。
在 Java 中,您不能这样做,因为您无法获取变量的地址。它根本不受支持。
Basically, you cannot implement
swap
method in Java.The reason you cannot do this is that Java argument has pass-by-value argument semantics. So when your
swap
method assignss2
tos1
and so on, it is operating entirely on the local variabless1
ands2
, and NOT on thes1
ands2
variables in the calling methodmain
.By contrast, if you were to implement the
swap
method in C, it would look something like this:and you would call it like this:
Notice that we are actually passing the address of a "pointer to char" variable.
In Java, you cannot do this because you cannot take the address of a variable. It is simply not supported.
最近有一个关于交换两个的一个非常类似的问题整数。 我的答案是使用原子引用:
当然,这不是很令人满意,因为您几乎不会针对 AtomicReferences 进行开发。但基本上你需要使用某种容器,因为你不能仅仅交换引用。因此,您可以交换二元素数组或列表的元素,但在无法访问原始变量的情况下无法交换两个字符串(因此您无法在辅助函数中执行此操作)。
There was a very similar question recently about swapping two ints. And my answer then was to use atomic references:
Of course this not very satisfactory, as you hardly ever develop against AtomicReferences. But basically you need to use some kind of container because you can't just swap the references. So you can e.g. swap the elements of a two-element array or list, but you just can't swap two strings without having access to the original variables (so you can't do it in a helper function).
Java
String
是通过引用实现的,因此您需要交换它们的引用。它会给你这个输出:
Java
String
s are implemented with references, so you need to swap their references.It will give you this output:
函数交换中的 s1 和 s2 变量是该函数的本地变量。
您需要将 s1 和 s2 定义为类的私有变量,或者从函数返回一个字符串数组。
The s1 and s2 variables in your function swap are local to that function.
You need to define s1 and s2 as private variables for your class, or return an array of strings from your function.
由于 Java 使用值传递,因此您定义的交换函数不会执行任何类型的交换;指针 s1 和 s2 在本地交换,但交换的结果不持久。您可以实现的最接近的事情是将要交换的项目包装在某个类中,并在该类中定义交换方法。这将允许您在此类的实例之间交换数据,尽管它实际上不会交换基础数据。举个例子:
Since Java uses pass-by-value, the swap function that you have defined does not do any sort of swapping; the pointers s1 and s2 are swapped locally, but the result of the swap does not persist. The closest thing you can achieve is to wrap the items you want to swap in some class and define a swap method in that class. This will allow you to swap data between instances of this class, although it will not actually swap the underlying data. As an example of this:
通过使用 StringBufferReader 和 StringBuilder 可以解决这个问题。首先从用户那里获取值,然后将它们拆分并存储在数组中。以相反的顺序运行 for 循环,以便最后一个字符串将被附加并首先显示,第一个字符串将最后显示。
输入:你好世界
输出:
By using
StringBufferReader
andStringBuilder
this can be solved. At 1st get the values from the user then split them and store them in array. Run the for loop in the reverse order so that the last string will be appended and displayed 1st the first will displayed last.input:hello world
output:
Java将内存中对象的地址传递给函数。然后函数中的某个局部变量保存该地址。如果您为这些局部变量分配一些新地址(另一个对象),则原始对象没有理由改变。
但是,将应用对原始对象的字段以及现有地址的更改。 (与c/c++中的
.
运算符相关)此链接 也可能有帮助。
Java passes the address of objects in the memory to functions. Then some local variable in the function holds that address. There is no reason for the original object to change if you assign some new address (another object) to those local variables.
However, changes to the fields of the original object, with the address in hand, ARE applied. (relate to
.
operator in c/c++)This link may also help.