在 Java 中交换两个字符串,通过将它们传递给实用程序函数,但不返回对象或使用包装类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3698323/
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
Swap two strings in Java, by passing them to a utility function, but without returning objects or using wrapper classes
提问by
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.
我正在尝试在 Java 中交换两个字符串。我从来没有真正理解“字符串是不可变的”。我在理论上理解它,但在实践中我从未遇到过。
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!
另外,由于 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;
}
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?
我认为 s1 和 s2 是引用,因此应该交换引用,新的应该分别指向另一个。我哪里错了?
采纳答案by Konrad Rudolph
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.
我认为 s1 和 s2 是引用,因此应该交换引用,新的应该分别指向另一个。
Yes. Locally insideswap
, this is exactly what happens.
是的。在本地内部swap
,这正是发生的事情。
However, s1
and s2
are copiesof the references passed into the function, so the effect remains local. Note that it's not the strings that are copied (since String
is a reference type). But the references arecopied.
但是,s1
和s2
是传递给函数的引用的副本,因此效果仍然是本地的。请注意,它不是复制的字符串(因为String
是引用类型)。但是引用是复制的。
… and since parameter references are alwayscopied in Java, writing a swap
function according to your specifications is, quite simply, not possible.
……而且由于参数引用总是在 Java 中复制,swap
因此根据您的规范编写函数是不可能的,很简单。
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 refersto her home so it's exactly like a Java reference.
嗯,一个地址指的是她的家,所以它就像一个 Java 引用。
回答by Stephen C
Basically, you cannot implement swap
method in Java.
基本上,您无法swap
在 Java 中实现方法。
The reason you cannot do this is that Java argument has pass-by-value argument semantics. So when your swap
method assigns s2
to s1
and so on, it is operating entirely on the localvariables s1
and s2
, and NOT on the s1
and s2
variables in the calling method main
.
您不能这样做的原因是 Java 参数具有按值传递参数语义。因此,当您的swap
方法分配s2
给s1
等等时,它完全对局部变量s1
and 进行操作s2
,而不是对调用方法中的s1
ands2
变量进行操作main
。
By contrast, if you were to implement the swap
method in C, it would look something like this:
相比之下,如果您要swap
在 C 中实现该方法,它将看起来像这样:
void swap(char ** s1, char ** s2) {
char * temp = *s1;
*s1 = *s2;
*s2 = temp;
}
and you would call it like this:
你会这样称呼它:
char *s1 = "Hello World";
char *s2 = "Goodbye World";
swap(&s1, &s2);
Notice that we are actually passing the address of a "pointer to char" variable.
请注意,我们实际上传递的是“指向 char 的指针”变量的地址。
In Java, you cannot do this because you cannot take the address of a variable. It is simply not supported.
在 Java 中,您不能这样做,因为您无法获取变量的地址。它根本不受支持。
回答by James Anderson
The s1 and s2 variables in your function swap are local to that function.
函数 swap 中的 s1 和 s2 变量是该函数的本地变量。
You need to define s1 and s2 as private variables for your class, or return an array of strings from your function.
您需要将 s1 和 s2 定义为您的类的私有变量,或者从您的函数返回一个字符串数组。
回答by Michael Aaron Safyan
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:
由于 Java 使用按值传递,因此您定义的交换函数不进行任何类型的交换;指针 s1 和 s2 在本地交换,但交换的结果不持久。您可以实现的最接近的事情是将要交换的项目包装在某个类中并在该类中定义一个交换方法。这将允许您在此类的实例之间交换数据,尽管它实际上不会交换基础数据。作为一个例子:
public class Swapper<T> {
public Swapper(T obj) {
data_ = obj;
}
public T get() { return data_; }
public void set(T value) { data_ = value; }
public void swap(Swapper<T> o) {
T tmp = o.data_;
o.data_ = data_;
data_ = tmp;
}
private T data_ = null;
}
// .. Now you can do:
Swapper<String> a = new Swapper("Hello");
Swapper<String> b = new Swapper("World");
// a.get().equals("Hello")
a.swap(b); // now a.get().equals("World")
回答by Sean Patrick Floyd
There was a very similar questionrecently about swapping two ints. And my answer thenwas to use atomic references:
最近有一个关于交换两个整数的非常相似的问题。然后我的答案是使用原子引用:
public void swap(AtomicReference<String> a, AtomicReference<String> b){
// update: look mom, no variables
a.set(b.getAndSet(a.get()));
}
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).
当然这不是很令人满意,因为您几乎没有针对 AtomicReferences 开发。但基本上你需要使用某种容器,因为你不能只是交换引用。所以你可以交换一个二元素数组或列表的元素,但是你不能在没有访问原始变量的情况下交换两个字符串(所以你不能在辅助函数中进行)。
回答by Andreas Dolk
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.
下面的代码是一个NoGo,永远不会实现这种反模式,永远不会改变不可变对象的私有 final 内部。不要怪我展示这个 hack,怪 Oracle 的 jvm 没有禁止它。
But, if one day you find some code where this works:
但是,如果有一天你找到了一些可以工作的代码:
String a = "Hello";
String b = "World";
String c = "World";
swap(a,b);
System.out.printf("%s %s%n", a,b); // prints: World Hello !!
System.out.println(c); // Side effect: prints "Hello" instead of "World"....
the implementation of swap
could look like this: (read on your own risk, I warned you!)
的实现swap
可能看起来像这样:(阅读您自己的风险,我警告过您!)
private void swap(String a, String b) {
try {
Field value = String.class.get("value");
value.setAccessible(true); // this should be forbidden!!
char[] temp = value.get(a);
value.set(a, value.get(b));
value.set(b, temp); // Aaargh, please forgive me
} catch(Exception e) {
e.printStackTrace(e);
}
}
回答by Atul
Java String
s are implemented with references, so you need to swap their references.
JavaString
是通过引用实现的,因此您需要交换它们的引用。
String s1 = "Hello";
String s2 = "World";
AtomicReference<String> String1 = new AtomicReference<String>(s1);
AtomicReference<String> String2 = new AtomicReference<String>(s2);
String1.set(String2.getAndSet(String1.get()));
System.out.println(String1 + " " + String2);
It will give you this output:
它会给你这个输出:
World Hello
回答by ashish
String s1 = "Hello";
String s2 = "World";
s1=s1+" "+s2;
s2=s1.split(" ")[0];
s1=s1.split(" ")[1];
System.out.println(s1 + " " + s2);
回答by Vijay Krishna
By using StringBufferReader
and StringBuilder
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:
通过使用StringBufferReader
,StringBuilder
可以解决这个问题。首先从用户那里获取值,然后将它们拆分并将它们存储在数组中。以相反的顺序运行 for 循环,以便将最后一个字符串附加并显示第一个,第一个将最后显示。输入:你好世界输出:
import java.io.*;
import java.util.*;
import java.lang.*;
public class Solution {
public static void main(String[] args) {
try {
int s,i,j;
StringBuilder str = new StringBuilder();
String st,t;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
t = br.readLine();
s = Integer.parseInt(t);
for (i = 0; i < s; i++) {
st=br.readLine();
String st1[]=st.split("\s+");
// System.out.println("l="+st1.length);
for (j = st1.length - 1; j >= 0; j--) {
str.append(st1[j] + " ");
}
System.out.println(str);
str.setLength(0);
}
} catch (Exception e) {
System.out.println(e);
}
}
}