将连字符分隔的单词(例如“do-some-stuff”)转换为较低的骆驼大小写变体(例如“doSomeStuff”)最优雅的方法是什么?

在Java中,将连字符分隔的单词(例如“do-some-stuff”)转换为较低的骆驼大小写变体(例如“doSomeStuff”)最优雅的方法是什么?

使用Guava的 CaseFormat

 import static com.google.common.base.CaseFormat.*; String result = LOWER_HYPHEN.to(LOWER_CAMEL, "do-some-stuff"); 

下面的方法应该在O(n)中处理相当高效的任务。 我们只是遍历XML方法名称的字符,跳过任何' – '和大写字母,如果需要的话。

 public static String toJavaMethodName(String xmlmethodName) { StringBuilder nameBuilder = new StringBuilder(xmlmethodName.length()); boolean capitalizeNextChar = false; for (char c:xmlMethodName.toCharArray()) { if (c == '-') { capitalizeNextChar = true; continue; } if (capitalizeNextChar) { nameBuilder.append(Character.toUpperCase(c)); } else { nameBuilder.append(c); } capitalizeNextChar = false; } return nameBuilder.toString(); } 

为什么不试试这个:

  1. 拆分“ – ”
  2. 大写每个单词,跳过第一个
  3. join

编辑 :第二个想法…虽然试图实现这一点,我发现没有简单的方法来join在Java中的string列表。 除非你从apache使用StringUtil 。 所以你将需要创build一个StringBuilder无论如何,因此该algorithm会变得有点丑陋:(

代码 :这是上面提到的一个例子。 有人可以用Java编译器(对不起,没有一个方便)来testing这个吗? 并用此处find的其他版本进行基准testing?

 public static String toJavaMethodNameWithSplits(String xmlMethodName) { String[] words = xmlMethodName.split("-"); // split on "-" StringBuilder nameBuilder = new StringBuilder(xmlMethodName.length()); nameBuilder.append(words[0]); for (int i = 1; i < words.length; i++) // skip first { nameBuilder.append(words[i].substring(0, 1).toUpperCase()); nameBuilder.append(words[i].substring(1)); } return nameBuilder.toString(); // join } 

如果你不喜欢依赖库,你可以使用正则expression式和String.format的组合。 使用正则expression式在-之后提取起始字符。 将这些用作String.formatinput。 有点棘手,但没有(爆炸)循环工作;)。

 public class Test { public static void main(String[] args) { System.out.println(convert("do-some-stuff")); } private static String convert(String input) { return String.format(input.replaceAll("\\-(.)", "%S"), input.replaceAll("[^-]*-(.)[^-]*", "$1-").split("-")); } } 

对于Java 8来说,最后是一个单行的

 Arrays.stream(name.split("\\-")) .map(String::toLowerCase) .map(s -> s.substring(0, 1).toUpperCase() + s.substring(1)) .collect(Collectors.joining()); 

虽然它分裂了4 实际行清晰ツ

(注意: "\\-"是针对每个问题的kebab-case,因为snake_case只是简单地改为"_"

这是安德烈亚斯的回答略微变化,比OP要求的更多:

 public static String toJavaMethodName(final String nonJavaMethodName){ final StringBuilder nameBuilder = new StringBuilder(); boolean capitalizeNextChar = false; boolean first = true; for(int i = 0; i < nonJavaMethodName.length(); i++){ final char c = nonJavaMethodName.charAt(i); if(!Character.isLetterOrDigit(c)){ if(!first){ capitalizeNextChar = true; } } else{ nameBuilder.append(capitalizeNextChar ? Character.toUpperCase(c) : Character.toLowerCase(c)); capitalizeNextChar = false; first = false; } } return nameBuilder.toString(); } 

它处理一些特殊情况:

  • fUnnY-cASe被转换为funnyCase
  • --dash-before-and--after- dashBeforeAndAfter转换为dashBeforeAndAfter
  • some.other$funky:chars? 被转换成someOtherFunkyChars

获取StringUtils的Apache commons jar。 然后你可以使用大写的方法

 import org.apache.commons.lang.StringUtils; public class MyClass{ public String myMethod(String str) { StringBuffer buff = new StringBuffer(); String[] tokens = str.split("-"); for (String i : tokens) { buff.append(StringUtils.capitalize(i)); } return buff.toString(); } } 

由于我并不是仅仅为了一种方法而增加一个库的忠实粉丝,我实现了我自己的解决scheme(从骆驼到蛇的案例):

 public String toSnakeCase(String name) { StringBuilder buffer = new StringBuilder(); for(int i = 0; i < name.length(); i++) { if(Character.isUpperCase(name.charAt(i))) { if(i > 0) { buffer.append('_'); } buffer.append(Character.toLowerCase(name.charAt(i))); } else { buffer.append(name.charAt(i)); } } return buffer.toString(); } 

需要根据进/出情况进行调整。

遍历string。 当你发现一个炒作,删除它,并大写下一个字母。