Java中反转字符串

时间:2020-02-23 14:34:39  来源:igfitidea点击:

用Java反向字符串是一个很好的与编码有关的面试问题。
我已经看到受访者尝试了多种方法来使用不同的方法来反转字符串。
这篇文章的想法是提供一些反转字符串的流行方法,并最终确定哪种是反转字符串的最佳和正确方法。

在Java中反转字符串

以下是一些在线查找Java程序中的字符串的流行方法。
注意,String中没有" reverse"方法,否则我们可以避免所有这些变通方法。

  • 使用StringBuilder或者StringBuffer反转字符串我们知道StringBuffer和StringBuilder类提供reverse方法,因此我们可以使用它来反转字符串。
    以下是显示如何使用StringBuilder反转字符串的代码段。

  • 使用Char Array反向字符串我们可以将String转换为char数组,然后反向遍历它,并从中填充第二个char数组。
    然后使用第二个char数组创建将与第一个相反的字符串。
    下面是此方法的代码。

  • 使用字节数组反转字符串与使用char数组的方法相同,但使用字节数组。
    代码如下所示。

逐字反转字符串

有时我们希望单词在句子中被颠倒,而不是一个字符一个字符地反转。
下面是一个简单的代码,显示了如何使用String split函数和StringBuilder来执行此操作。

String input = "java";
StringBuilder sb = new StringBuilder(input);
String result = sb.reverse().toString();
System.out.println(result); //prints 'avaj'

在Java中反转String的最佳方法?

因此,从以上三种方法来看,这是正确和最佳的方法。
正如您在上面看到的那样,这三种方法对于简单的给定输入都可以正常工作。
如果您阅读String类javadoc,那么它有一些有趣的地方。

字符串表示采用UTF-16格式的字符串,其中补充字符由代理对表示(有关更多信息,请参见Character类中的Unicode字符表示部分)。
索引值指的是字符代码单位,因此补充字符在String中使用两个位置。

除了用于处理Unicode代码单元(即char值)的方法外,String类还提供用于处理Unicode代码点(即字符)的方法。

因此,对于某些Unicode字符而言,它将在char数组或者字节数组中占据两个索引位置。
它对我们上面看到的反转String的代码有任何影响吗?让我们通过编写一个简单的类来找出答案,在该类中,我们将使用Scanner类接收用户输入,并使用上述所有三种方法将其取反。

String input = "java";
char [] ca = input.toCharArray();
char [] result = new char [ca.length];
int len = ca.length;
for(char c : ca) {
	result[len-1] = c;
	len--;
}
System.out.println(new String(result));

以下是其中一个测试运行的示例输出。

String input = "java";
byte [] ba = input.getBytes();
byte [] result = new byte [ba.length];
int len = ba.length;
for(byte b : ba) {
	result[len-1] = b;
	len--;
}
System.out.println(new String(result));

因此,似乎所有方法对于基于String的普通英语字符都可以正常工作。
现在下图显示了另一个运行,其中输入字符串中存在Unicode字符。

因此,在上述情况下,字节数组反向无法正常工作。
但是,StringBuilder和char数组方法可以正常工作。
我没有尝试使用补充字符作为上述程序的输入字符串,但是如果我查看StringBuilder反向函数API的javadoc,它会说:

使此字符序列被序列的相反字符替换。
如果序列中包含任何代理对,则将它们视为反向操作的单个字符。
因此,从高到低的替代物的顺序永远不会颠倒。
令n为恰好执行反向方法之前此字符序列的字符长度(而不是char值中的长度)。
然后,新字符序列中索引k处的字符等于旧字符序列中索引n-k-1处的字符。

因此,似乎在StringBuilder reverse()方法中已处理了补字符。
这就是为什么如果需要反转字符串,我的建议是使用StringBuilder reverse()方法。