[英]Java method to reverse upper-lower case doesn't reverse all letters
我想创建一种方法来反转单词中的大写字母。 我遇到的问题是该方法不会反转所有字母。 例如,当我输入“nIceToMeEtyoU”时,它会打印“NiCETomEETYou”。 它不适用于“o”、第二个“e”和“t”。 我只是无法弄清楚代码有什么问题。
public static String reverseCase(String str) {
char changed;
String a = str;
for (int i = 0; i < a.length(); i++) {
char d = a.charAt(i);
boolean letter = Character.isUpperCase(d);
if (letter == true) {
changed = Character.toLowerCase(d);
} else {
changed = Character.toUpperCase(d);
}
a = a.replace(d, changed);
}
return a;
}
String::replace
返回一个新字符串,其中所有出现的要替换的字符都已更改。
此外,Java 中的字符串是不可变的,这意味着您不能在保持相同字符串的同时替换字符串中的字符。 为了替换特定索引处的字符,请参阅此帖子
它不适用于“o”、“second e”和“t”。
replace() 方法替换字符串中所有出现的字符。
相反,当您遍历字符串时,使用StringBuffer
来附加每个字符。
然后当循环完成时,您使用StringBuffer
的 toString() 方法重新创建 String 。
我建议您使用StringBuilder
构建字符串,而不是使用String#replace
将匹配的所有实例替换为给定的替换,如下所示:
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(reverseCase("nIceToMeEtyoU"));
System.out.println(reverseCase("NiCETomEETYou"));
}
public static String reverseCase(String str) {
StringBuilder sb = new StringBuilder();
// Use the enhanced for loop
for (char ch : str.toCharArray()) {
if (Character.isUpperCase(ch)) {
ch = Character.toLowerCase(ch);
} else {
ch = Character.toUpperCase(ch);
}
sb.append(ch);
}
return sb.toString();
}
}
输出:
NiCEtOmEeTYOu
nIcetOMeetyOU
使用您的方法,无论在一次传递中更改哪个字符,如果在这些传递中再次找到它们,都将在下一次传递中恢复。
replace
替换字符串中所有出现的字符。 因此,例如,当您第一次遇到e
您会将所有的e
替换为E
。 然后,当遇到下一个“原始” e
(现在是E
)时,所有E
s 将变回e
s ,依此类推。
您可以在新对象中累积遇到的字符,而不是使用replace
。 虽然您可以使用String
并使用+=
运算符添加到它,但使用StringBuilder
应该具有更好的性能:
public static String reverseCase(String str) {
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < str.length(); i++) {
char c = a.charAt(i);
id (Character.isUpperCase(c) {
c = Character.toLowerCase(c);
} else i (Character.isLowerCase(c)) {
c = Character.toLowerCase(c);
}
sb.append(c);
}
return st.toString();
}
您可以连接每个字符以创建一个新字符串,而不是使用替换(替换字符串中的所有出现)。
public static String reverseCase(String input) {
StringBuilder a = new StringBuilder();
for (char c : input.toCharArray()) {
a.append(Character.isUpperCase(c) ? Character.toLowerCase(c) : Character.toUpperCase(c));
}
return a.toString();
}
您可以将 StringBuilder 用于其他线程无法访问的字符串操作。 您在这里面临的主要问题是因为其他人提到的 replace() 方法。 replace() 方法替换字符串中所有出现的字符。 而不是尝试替换,只需构建新字符串并返回。 另一种方法是创建一个字符数组并替换循环内当前位置的字符(使用变量:'changed')。
public static String reverseCase(String str) {
char changed;
StringBuilder reversedStringBuilder=new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char d = str.charAt(i);
boolean letter = Character.isUpperCase(d);
if (letter) {
changed = Character.toLowerCase(d);
} else {
changed = Character.toUpperCase(d);
}
reversedStringBuilder.append(changed);
}
return reversedStringBuilder.toString();
}
public static void main(String[] args) {
System.out.println(reverseCase("nIceToMeEtyoU"));
}
a.replace(d, changed)
替换字符串中出现的每个d
,而不仅仅是您正在查看的索引处的那个。
o
发生的事情。 当您遇到第一个o
,两个出现都被替换为大写O
。 当你遇到下一个O
,它已经是大写了,所以两个出现的地方又变成了小写。e
和一次E
首先将两个小写的e
改为大写。 其次,所有三个都改为小写。 第三,全部为大写。 相反,不要直接在字符串中执行替换。 使用StringBuffer
或StringBuilder
或char
数组。 在其中的每一个中,您都可以按索引执行替换,以便您只影响您打算影响的字母的出现。
额外提示: if (letter == true)
被认为是平庸的风格。 更喜欢if (letter)
。
奖励信息:存在在切换大小写时变成多个字母的字母。 如果我输入德语单词Füße
( feet ),则ß
仅以小写形式存在,而在大写形式中变为SS
。 所以这个词的正确fÜSSE
应该是fÜSSE
。 但是, Character.toUpperCase()
不能返回两个字符,所以将它留在ß
。
import java.util.stream.Collectors;
public class FlipCase {
static char flipCase(char ch) {
if (Character.isUpperCase(ch)) return Character.toLowerCase(ch);
else return Character.toUpperCase(ch);
}
public static String reverseCase(String str) {
return str
.chars()
.mapToObj(i -> (char) i)
.map(ch -> String.valueOf(FlipCase.flipCase(ch)))
.collect(Collectors.joining());
}
public static void main(String[] args) {
System.out.println(reverseCase("nIceToMeEtyoU")); // NiCEtOmEeTYOu
}
}
如前所述,问题是replace
。 最好使用StringBuilder
并创建一个新字符串。
我还提供了一个您可能会感兴趣的替代方案。
您可以通过将位从大写翻转到小写来实现,反之亦然。
关键是要知道右起第六位是Strings
案例之间的位(如您的示例)。 那将是 2 到 5 或 32。异或运算符 ( ^
) 可用于翻转位。
String s = "nIceToMeEtyoU";
System.out.println(reverseCase(s));
public static String reverseCase(String s) {
StringBuilder sb = new StringBuilder(s.length());
for(char c : s.toCharArray()) {
// change the case if letter
sb.append(Character.isLetter(c) ? (char) (c ^ 32) : c);
}
return sb.toString();
}
印刷
NiCEtOmEeTYOu
您之前尝试过Apache Commons吗? 我确信这是处理这种情况的最简单方法:
package com.awm4n.swapcaseexample;
import org.apache.commons.lang3.StringUtils;
public class SwapCaseExample {
public static void main(String[] args) {
String str = "TheMOStsimPLEWAytoswaPCASE";
System.out.println( StringUtils.swapCase(str) );
}
}
输出将是:
tHEmosTSIMplewaYTOSWApcase
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.