Java逆转大小写的方法不会逆转所有字母

问题描述

我想创建一种方法来反转单词中的大小写字母。我遇到的问题是该方法不会反转所有字母。例如,当我键入“ 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中的字符串是不可变的,这意味着您不能在保留相同字符串的情况下替换字符串中的字符。 为了替换特定索引处的字符,请参见this post

,

它不适用于“ o”,“ second e”和“ t”。

replace()方法替换字符串中所有出现的字符。

相反,在遍历字符串时,请使用StringBuffer附加每个字符。

然后,当循环结束时,您可以使用StringBuffer的toString()方法重新创建String。

,

建议您使用String#replace来构建字符串,而不是使用StringBuilder来将匹配的所有实例替换为给定的替换,如下所示:

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将被转回到e,依此类推。 / p>

代替使用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();
}
,

代替使用replace(替换字符串中所有出现的内容),您可以合并每个字符以创建新字符串。

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 for String操作,其他线程无法访问它。您在这里面临的主要问题是由于其他人提到的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更改为大写。第二个alll 3更改为小写。第三,全部为大写。

相反,请勿直接在字符串中执行替换。使用StringBufferStringBuilderchar数组。在每种方法中,您都可以按索引执行替换操作,以便仅影响打算影响的字母的出现。

奖金提示:if (letter == true)被认为是中等风格。仅推荐if (letter)

奖金信息:切换大小写时,存在多个字母的字母。如果输入德语单词Füße feet ),则ß仅存在小写字母,而变成大写的SS。因此,单词的正确反向将是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