What is the simplest way to convert a Java string from all caps (words separated by underscores) to CamelCase (no word separators)?

Viewed 253058

The title pretty much says it all. What's the simplest/most elegant way that I can convert, in Java, a string from the format "THIS_IS_AN_EXAMPLE_STRING" to the format "ThisIsAnExampleString"? I figure there must be at least one way to do it using String.replaceAll() and a regex.

My initial thoughts are: prepend the string with an underscore (_), convert the whole string to lower case, and then use replaceAll to convert every character preceded by an underscore with its uppercase version.

22 Answers

Take a look at WordUtils in the Apache Commons lang library:

Specifically, the capitalizeFully(String str, char[] delimiters) method should do the job:

String blah = "LORD_OF_THE_RINGS";
assertEquals("LordOfTheRings", WordUtils.capitalizeFully(blah, '_').replaceAll("_", ""));

Green bar!

static String toCamelCase(String s){
   String[] parts = s.split("_");
   String camelCaseString = "";
   for (String part : parts){
      camelCaseString = camelCaseString + toProperCase(part);
   }
   return camelCaseString;
}

static String toProperCase(String s) {
    return s.substring(0, 1).toUpperCase() +
               s.substring(1).toLowerCase();
}

Note: You need to add argument validation.

Here is a code snippet which might help:

String input = "ABC_DEF";
StringBuilder sb = new StringBuilder();
for( String oneString : input.toLowerCase().split("_") )
{
    sb.append( oneString.substring(0,1).toUpperCase() );
    sb.append( oneString.substring(1) );
}

// sb now holds your desired String
public static void main(String[] args) {
    String start = "THIS_IS_A_TEST";
    StringBuffer sb = new StringBuffer();
    for (String s : start.split("_")) {
        sb.append(Character.toUpperCase(s.charAt(0)));
        if (s.length() > 1) {
            sb.append(s.substring(1, s.length()).toLowerCase());
        }
    }
    System.out.println(sb);
}

The Apache Commons project does now have the CaseUtils class, which has a toCamelCase method that does exactly as OP asked:

 CaseUtils.toCamelCase("THIS_IS_AN_EXAMPLE_STRING", true, '_');

You can use org.modeshape.common.text.Inflector.

Specifically:

String camelCase(String lowerCaseAndUnderscoredWord,
    boolean uppercaseFirstLetter, char... delimiterChars) 

By default, this method converts strings to UpperCamelCase.

Maven artifact is: org.modeshape:modeshape-common:2.3.0.Final

on JBoss repository: https://repository.jboss.org/nexus/content/repositories/releases

Here's the JAR file: https://repository.jboss.org/nexus/content/repositories/releases/org/modeshape/modeshape-common/2.3.0.Final/modeshape-common-2.3.0.Final.jar

public static String toCamelCase(String value) {
    value = value.replace("_", " ");
    String[] parts = value.split(" ");
    int i = 0;
    String camelCaseString = "";
    for (String part : parts) {
        if (part != null && !part.isEmpty()) {
            if (i == 0) {
                camelCaseString = part.toLowerCase();
            } else if (i > 0 && part.length() > 1) {
                String oldFirstChar = part.substring(0, 1);
                camelCaseString = camelCaseString + part.replaceFirst(oldFirstChar, oldFirstChar.toUpperCase());
            } else {
                camelCaseString = camelCaseString + part + " ";
            }
            i++;
        }
    }
    return camelCaseString;
}

public static void main(String[] args) {
    String string = "HI_tHiS_is_SomE Statement";
    System.out.println(toCamelCase(string));
}

Sorry for mine five cents, I think in java too many words)) I just wondering. Why is the regexp engine in java not so familiar with lambdas as in JS((

Anyway. With java 8+ construction appears in my mind:

Arrays.stream("THIS_IS_AN_EXAMPLE_STRING".split("_"))
    .collect(StringBuilder::new,
        (result, w) -> result
            .append(w.substring(0, 1).toUpperCase())
            .append(w.substring(1).toLowerCase()),
        StringBuilder::append)
    .toString())

If you care about memory consumption, the below code care about it:

"THIS_IS_AN_EXAMPLE_STRING".chars().collect(StringBuilder::new,
    (result, c) -> {
        // Detect place for deal with
        if (result.length() > 0 && result.charAt(result.length() - 1) == '_') {
            result.setCharAt(result.length() - 1,
                    Character.toUpperCase((char) c));
        } else if (result.length() > 0) {
            result.append(Character.toLowerCase((char) c));
        } else {
            result.append(Character.toUpperCase((char) c));
        }
    }, StringBuilder::append).toString()
    protected String toCamelCase(CaseFormat caseFormat, String... words){
        if (words.length  == 0){
          throw new IllegalArgumentException("Word list is empty!");
        }

        String firstWord = words[0];
        String [] restOfWords = Arrays.copyOfRange(words, 1, words.length);

        StringBuffer buffer = new StringBuffer();
        buffer.append(firstWord);
        Arrays.asList(restOfWords).stream().forEach(w->buffer.append("_"+ w.toUpperCase()));

        return CaseFormat.UPPER_UNDERSCORE.to(caseFormat, buffer.toString());

    }

Java 8 for multiple strings:

import com.google.common.base.CaseFormat;



String camelStrings = "YOUR_UPPER, YOUR_TURN, ALT_TAB";

List<String> camelList = Arrays.asList(camelStrings.split(","));
camelList.stream().forEach(i -> System.out.println(CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, i) + ", "));
Related