【问题标题】:How can I invert the case of a String in Java?如何在 Java 中反转字符串的大小写?
【发布时间】:2010-12-16 07:57:56
【问题描述】:

我想更改一个字符串,使所有大写字符变为小写,所有小写字符变为大写。数字字符会被忽略。

所以“AbCdE123”变成了“aBcDe123”

我想一定有一种方法可以遍历字符串并翻转每个字符,或者可能是一些可以做到这一点的正则表达式。

【问题讨论】:

  • 不,这种情况下不能使用正则表达式。

标签: java string case case-sensitive


【解决方案1】:

Apache Commons StringUtils 有一个swapCase 方法。

【讨论】:

  • 他们的 StringUtils 是处理字符串的最佳工具之一。
  • 可能会反对将依赖项添加到大型库中仅用于复杂性非常有限的单个函数。
  • 同意依赖关系,但如果你环顾四周,你可能会发现其他地方 Commons 代码可以简化你的代码。
  • 我还要补充一点,使用已知经过大量测试和广泛使用的方法(例如 Apache Commons)具有优势。如果您自己实现了它,您的基本算法可能没有任何问题,但是(除非您让 Jon Skeet 为您编写它)您可能会遇到一点点错误或一些直到出现才会出现的错误稍后。
【解决方案2】:

我想一定有办法遍历字符串并翻转每个字符

正确。 java.lang.Character 类为您提供了每个 isUpperCase() 方法。对其进行测试并根据结果使用toLowerCase()toUpperCase() 方法。将每个结果附加到StringBuilder,你应该没问题。

【讨论】:

  • 无需附加到 StringBuilder - 您已经确切知道输出将有多大,并且可以就地在数组中完成。
  • 如果他事后不需要操纵的话,确实是可以做到的。
  • Jon:如果您遵守特定于语言环境的规则,则更改字符串的大小写不一定保持长度。例如。对于德语语言环境,“ß”的大写是“SS”。
【解决方案3】:

我不相信有任何内置功能可以做到这一点(这相对不寻常)。不过应该这样做:

public static String reverseCase(String text)
{
    char[] chars = text.toCharArray();
    for (int i = 0; i < chars.length; i++)
    {
        char c = chars[i];
        if (Character.isUpperCase(c))
        {
            chars[i] = Character.toLowerCase(c);
        }
        else if (Character.isLowerCase(c))
        {
            chars[i] = Character.toUpperCase(c);
        }
    }
    return new String(chars);
}

请注意,这不会像 String.toUpperCase/String.toLowerCase 那样进行特定于语言环境的更改。它也不处理非 BMP 字符。

【讨论】:

  • @JacobM:他们到底是如何构建数组的?我发现转到一个 char 数组,就地修改,然后在最后构建一个 String 是执行此类工作的更有效方法之一。
  • 看起来他们首先分配一个 StringBuffer 并将每个转换后的字符附加到缓冲区。我想问题是 StringBuffer.toString 是否比 new String(char[]) 效率更高或更低。我不能告诉你。源代码在kickjava.com/src/org/apache/commons/lang/StringUtils.java.htm
  • 通过使用 StringBuffer 而不是 StringBuilder,他们已经在每个操作上招致了(小的)同步损失。然后是 StringBuffer 的内部管理,保持长度与容量等。我并不是说这是一个很大的不同 - 但在这两种情况下都会有一个额外的(不可避免的)额外的副本,我看不到任何实际的StringBuffer 方法的优势。
  • 这正在迅速演变为迂腐,无论如何调用 StringBuffer.toString() 会通过调用包私有 String 构造函数重用 char[] 数组。我刚刚检查过,在 1.5+ 中不再是这种情况,StringBuilder 和 StringBuffer 的 toString 方法复制了 char 数组。无论如何,我更喜欢 char[] 方法。
  • Sam:String(Buffer|Builder).toString 在早期的 Java 版本中也必须创建一个副本,因为对 StringBuffer 的修改不会导致对先前创建的 String 实例的更改。
【解决方案4】:

我确实意识到给定的线程已经很老了,但是有更好的解决方法:

class Toggle
{ 
    public static void main()
    { 
        String str = "This is a String";
        String t = "";
        for (int x = 0; x < str.length(); x++)
        {  
            char c = str.charAt(x);
            boolean check = Character.isUpperCase(c);
            if (check == true)
                t = t + Character.toLowerCase(c);
            else
                t = t + Character.toUpperCase(c);
        }
        System.out.println (t);
    }
}

【讨论】:

  • 您愿意解释一下为什么这会“更好”吗?它(功能)与the already accepted answer 没有(非常)不同。但是,您确实没有使用固定长度的数组或字符串生成器,因此从这个意义上说,您的解决方案甚至更糟,因为需要更多(重新)分配。另一件事是您要引入一个变量check,至少它不是很具有描述性。还;这是风格/品味的问题,但如果由我决定,我会写 if (Character.isUpperCase(c)) 而不是先分配 check 然后检查变量...
【解决方案5】:

我们也可以使用 StringBuilder 对象,因为它有字符替换方法。但是,存储 StringBuilder 对象可能需要一些额外的空间。因此,如果空间无关紧要并保持解决方案简单易懂,这将有所帮助。

String swapCase(String text) {
    StringBuilder textSB = new StringBuilder(text);
    for(int i = 0; i < text.length(); i++) {
        if(text.charAt(i) > 64 && text.charAt(i) < 91)
            textSB.setCharAt(i, (char)(text.charAt(i) + 32));
        else if(text.charAt(i) > 96 && text.charAt(i) < 123)
            textSB.setCharAt(i, (char)(text.charAt(i) - 32));
    }
    return textSB.toString();
}

【讨论】:

    【解决方案6】:

    基于 Faraz 的方法,我认为字符转换可以这么简单:

    t += Character.isUpperCase(c) ? Character.toLowerCase(c) : Character.toUpperCase(c);
    

    【讨论】:

      【解决方案7】:

      Java 8 及以上版本:

      String myString = "MySampleString123";
      System.out.println(myString.chars().map(c -> Character.isLetter(c) ? c ^ ' ' : c).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString());
      

      要注意反转字母大小写的代码:

      Character.isLetter(c) ? c ^ ' ' : c
      

      【讨论】:

      • 我刚刚使用计算器根据 ascii 表索引验证(XORing with space),它似乎有效,但我以前从未听说过这个,所以你能解释一下为什么它有效? ASCII 表的设计从一开始就考虑到这一点吗?
      • stackoverflow.com/a/52650157/3225638 这个答案表明这是一个深思熟虑的决定,虽然这是一个该死的好把戏
      • @Lorenzo 它是经过精心设计的,在第 6 位通过设置/取消设置来切换字母的大小写
      【解决方案8】:
      public class ReverseCase {
          public  static void main(String[] args){ 
              char[] char_arr = args[0].toCharArray();
              for (int i = 0; i < char_arr.length; i++) {
                  if (Character.isLowerCase(char_arr[i])) {
                      char_arr[i] = Character.toUpperCase(char_arr[i]);
                  }else {
                      char_arr[i] = Character.toLowerCase(char_arr[i]);
                  }
              }
              String reversed = new String(char_arr);
              System.out.println(reversed);
          }
      }
      

      【讨论】:

        【解决方案9】:

        我认为最容易理解的解决方案是:

        public static String reverseCase(String text) {
            StringBuilder sb = new StringBuilder();
            for (char c : text.toCharArray())
                sb.append(Character.isUpperCase(c) ? 
                        Character.toLowerCase(c) : 
                        Character.toUpperCase(c));
            return sb.toString();
        }
        

        我认为您可以更轻松地阅读此内容,并且 StringBuilder 有一个 append(char) 方法 + Character.toUpperCasetoLowerCase 都只是静态方法。我只是对唯一的 StringBuilder 示例也包含 ascii 索引算法感到难过。

        对于那些不喜欢三元表达式的人,这里是等价的:

        public static String reverseCase(String text) {
            StringBuilder sb = new StringBuilder();
            for (char c : text.toCharArray())
                if (Character.isUpperCase(c)) 
                    c = Character.toLowerCase(c);
                else
                    c = Character.toUpperCase(c);
                sb.append(c);
            return sb.toString();
        }
        

        编辑 Java 8+(StringBuilder 收集器代码取自 @Arun 的答案)

        public static String reverseCase(String text) {
            return text.chars()
                .map(c -> Character.isUpperCase(c) ? 
                    Character.toLowerCase(c) : 
                    Character.toUpperCase(c))
                .collect(
                    StringBuilder::new,
                    StringBuilder::appendCodePoint,
                    StringBuilder::append)
                .toString();
        }
        

        【讨论】:

        • 为什么不呢? sb.append(Character.isUpperCase(c) ? Character.toLowerCase(c) : Character.isUpperCase(c));
        • 嗯,我认为您的意思是 Character.toUpperCase 用于 if false 条件,但我想您是对的,让我清理一下
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-03
        • 2011-01-16
        • 1970-01-01
        • 2010-12-29
        • 1970-01-01
        • 2021-06-11
        • 1970-01-01
        相关资源
        最近更新 更多