¿Cuál es la forma más simple de convertir una cadena Java de mayúsculas (palabras separadas por guiones bajos) a CamelCase (sin separadores de palabras)?

El título lo dice todo. ¿Cuál es la forma más simple / más elegante que puedo convertir, en Java, una cadena del formato "THIS_IS_AN_EXAMPLE_STRING" al formato ” ThisIsAnExampleString “? Me imagino que debe haber al menos una forma de hacerlo usando String.replaceAll() y una expresión regular.

Mis pensamientos iniciales son: anteponer la cadena con un guión bajo ( _ ), convertir toda la cadena en minúscula y luego usar replaceAll para convertir cada carácter precedido por un guión bajo con su versión en mayúscula.

Otra opción es usar com.google.common.base.CaseFormat Google Guava

George Hawkins dejó un comentario con este ejemplo de uso:

 CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, "THIS_IS_AN_EXAMPLE_STRING"); 

Eche un vistazo a WordUtils en la biblioteca Apache Commons lang :

Específicamente, el método capitalizeFully (String str, char [] delimitadores) debería hacer el trabajo:

 String blah = "LORD_OF_THE_RINGS"; assertEquals("LordOfTheRings", WordUtils.capitalizeFully(blah, new char[]{'_'}).replaceAll("_", "")); 

¡Bar verde!

 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(); } 

Nota : Necesita agregar validación de argumentos.

Con Apache Commons Lang3 lib es muy fácil.

 import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; public String getName(String text) { return StringUtils.remove(WordUtils.capitalizeFully(text, '_'), "_"); } 

Ejemplo:

 getName("SOME_CONSTANT"); 

Da:

 "SomeConstant" 
 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); } 

Aquí hay un fragmento de código que podría ayudar:

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

No estoy seguro, pero creo que puedo usar menos memoria y obtener un rendimiento confiable al hacerlo char-by-char. Estaba haciendo algo similar, pero en loops en hilos de fondo, así que estoy intentando esto por ahora. He tenido cierta experiencia con String.split siendo más caro de lo esperado. Y estoy trabajando en Android y espero que el hipo de GC sea un problema mayor que el uso de la CPU.

  public static String toCamelCase(String value) { StringBuilder sb = new StringBuilder(); final char delimChar = '_'; boolean lower = false; for (int charInd = 0; charInd < value.length(); ++charInd) { final char valueChar = value.charAt(charInd); if (valueChar == delimChar) { lower = false; } else if (lower) { sb.append(Character.toLowerCase(valueChar)); } else { sb.append(Character.toUpperCase(valueChar)); lower = true; } } return sb.toString(); } 

Una sugerencia de que String.split es costoso es que su entrada es una expresión regular (no una char como String.indexOf) y devuelve una matriz (en lugar de decir un iterador porque el ciclo solo usa elementos de uno en uno). Además, casos como "AB_AB_AB_AB_AB_AB ..." rompen la eficiencia de cualquier copia masiva, y para cadenas largas usan un orden de magnitud más de memoria que la cadena de entrada.

Mientras que recorrer los caracteres no tiene un caso canónico. Por lo tanto, para mí, la sobrecarga de una matriz y expresiones regulares innecesarias parece generalmente menos preferible (luego se abandona la posible eficacia de la copia masiva). Interesado en escuchar opiniones / correcciones, gracias.

 public String withChars(String inputa) { String input = inputa.toLowerCase(); StringBuilder sb = new StringBuilder(); final char delim = '_'; char value; boolean capitalize = false; for (int i=0; i 

Tiempos: en milisegundos.

 Iterations = 1000 WithChars: start = 1379685214671 end = 1379685214683 diff = 12 WithRegex: start = 1379685214683 end = 1379685214712 diff = 29 Iterations = 1000 WithChars: start = 1379685217033 end = 1379685217045 diff = 12 WithRegex: start = 1379685217045 end = 1379685217077 diff = 32 Iterations = 1000 WithChars: start = 1379685218643 end = 1379685218654 diff = 11 WithRegex: start = 1379685218655 end = 1379685218684 diff = 29 Iterations = 1000000 WithChars: start = 1379685232767 end = 1379685232968 diff = 201 WithRegex: start = 1379685232968 end = 1379685233649 diff = 681 Iterations = 1000000 WithChars: start = 1379685237220 end = 1379685237419 diff = 199 WithRegex: start = 1379685237419 end = 1379685238088 diff = 669 Iterations = 1000000 WithChars: start = 1379685239690 end = 1379685239889 diff = 199 WithRegex: start = 1379685239890 end = 1379685240585 diff = 695 Iterations = 1000000000 WithChars: start = 1379685267523 end = 1379685397604 diff = 130081 WithRegex: start = 1379685397605 end = 1379685850582 diff = 452977 

Ejemplo de Java 1.8 usando Streams

 String text = "THIS_IS_SOME_TEXT"; String bactrianCamel = Stream.of(text.split("[^a-zA-Z0-9]")) .map(v -> v.substring(0, 1).toUpperCase() + v.substring(1).toLowerCase()) .collect(Collectors.joining()); String dromedaryCamel = bactrianCamel.toLowerCase().substring(0, 1) + bactrianCamel.substring(1); System.out.printf("%s is now %s%n", text, dromedaryCamel); 

THIS_IS_SOME_TEXT ahora es thisIsSomeText

Puede usar org.modeshape.common.text.Inflector .

Específicamente:

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

Por defecto, este método convierte cadenas en UpperCamelCase.

El artefacto de Maven es: org.modeshape: modeshape-common: 2.3.0.Final

en el repository de JBoss: https://repository.jboss.org/nexus/content/repositories/releases

Aquí está el archivo JAR: https://repository.jboss.org/nexus/content/repositories/releases/org/modeshape/modeshape-common/2.3.0.Final/modeshape-common-2.3.0.Final.jar

Puedes probar esto también:

  public static String convertToNameCase(String s) { if (s != null) { StringBuilder b = new StringBuilder(); String[] split = s.split(" "); for (String srt : split) { if (srt.length() > 0) { b.append(srt.substring(0, 1).toUpperCase()).append(srt.substring(1).toLowerCase()).append(" "); } } return b.toString().trim(); } return s; } 

Convertirá a Enum Constant en Camel Case. Sería útil para cualquiera que esté buscando esa funcionalidad.

 public enum TRANSLATE_LANGUAGES { ARABIC("ar"), BULGARIAN("bg"), CATALAN("ca"), CHINESE_SIMPLIFIED("zh-CN"), CHINESE_TRADITIONAL("zh-TW"), CZECH("cs"), DANISH("da"), DUTCH("nl"), ENGLISH("en"), ESTONIAN("et"), FINNISH("fi"), FRENCH( "fr"), GERMAN("de"), GREEK("el"), HAITIAN_CREOLE("ht"), HEBREW("he"), HINDI("hi"), HMONG_DAW("mww"), HUNGARIAN("hu"), INDONESIAN("id"), ITALIAN("it"), JAPANESE("ja"), KOREAN("ko"), LATVIAN( "lv"), LITHUANIAN("lt"), MALAY("ms"), NORWEGIAN("no"), PERSIAN("fa"), POLISH("pl"), PORTUGUESE("pt"), ROMANIAN("ro"), RUSSIAN("ru"), SLOVAK("sk"), SLOVENIAN("sl"), SPANISH("es"), SWEDISH( "sv"), THAI("th"), TURKISH("tr"), UKRAINIAN("uk"), URDU("ur"), VIETNAMESE("vi"); private String code; TRANSLATE_LANGUAGES(String language) { this.code = language; } public String langCode() { return this.code; } public String toCamelCase(TRANSLATE_LANGUAGES lang) { String toString = lang.toString(); if (toString.contains("_")) { String st = toUpperLowerCase(toString.split("_")); } return ""; } private String toUpperLowerCase(String[] tempString) { StringBuilder builder = new StringBuilder(); for (String temp : tempString) { String char1 = temp.substring(0, 1); String restString = temp.substring(1, temp.length()).toLowerCase(); builder.append(char1).append(restString).append(" "); } return builder.toString(); } } 

Una solución más a esto puede ser la siguiente.

 public static String toCamelCase(String str, String... separators) { String separatorsRegex = "\\".concat(org.apache.commons.lang3.StringUtils.join(separators, "|\\")); List splits = Arrays.asList(str.toLowerCase().split(separatorsRegex)); String capitalizedString = (String)splits.stream().map(WordUtils::capitalize).reduce("", String::concat); return capitalizedString.substring(0, 1).toLowerCase() + capitalizedString.substring(1); } 
 public static final String UPPER_CAMEL = "initUp"; public static final String LOWER_CAMEL = "initLow"; public String toCamel(String src, String separator, String format) { StringBuilder builder = new StringBuilder(src.toLowerCase()); int len = builder.length(); for (int idx = builder.indexOf(separator); idx > 0 && idx < len; idx = builder.indexOf(separator, idx)) { builder = builder.replace(idx, idx + 2, (String.valueOf(builder.charAt(idx + 1)).toUpperCase())); } switch (format) { case LOWER_CAMEL: builder.setCharAt(0, Character.toLowerCase(builder.charAt(0))); break; default: builder.setCharAt(0, Character.toUpperCase(builder.charAt(0))); break; } return builder.toString(); } 

Invocación como

 toCamel("THIS_IS_AN_EXAMPLE_STRING", "_", UPPER_CAMEL) 

Tiempo de ejecución: 14 ms

 protected String toCamelCase(String input) { if (input == null) { return null; } if (input.length() == 0) { return ""; } // lowercase the first character String camelCaseStr = input.substring(0, 1).toLowerCase(); if (input.length() > 1) { boolean isStartOfWord = false; for (int i = 1; i < input.length(); i++) { char currChar = input.charAt(i); if (currChar == '_') { // new word. ignore underscore isStartOfWord = true; } else if (Character.isUpperCase(currChar)) { // capital letter. if start of word, keep it if (isStartOfWord) { camelCaseStr += currChar; } else { camelCaseStr += Character.toLowerCase(currChar); } isStartOfWord = false; } else { camelCaseStr += currChar; isStartOfWord = false; } } } return camelCaseStr; } 
 public String CamelCase(String str) { String CamelCase=""; String parts[] = str.split("_"); for(String part:parts) { String as=part.toLowerCase(); int a=as.length(); CamelCase = CamelCase + as.substring(0, 1).toUpperCase()+ as.substring(1,a); } return CamelCase; } 

Este es el progtwig más simple para convertir a CamelCase. Espero que te ayude..

Un snnipet simple:

  public static String camelCase(String in) { if (in == null || in.length() < 1) { return ""; } //validate in String out = ""; for (String part : in.toLowerCase().split("_")) { if (part.length() < 1) { //validate length continue; } out += part.substring(0, 1).toUpperCase(); if (part.length() > 1) { //validate length out += part.substring(1); } } return out; } 

Java 8 para múltiples cadenas:

 import com.google.common.base.CaseFormat; String camelStrings = "YOUR_UPPER, YOUR_TURN, ALT_TAB"; List camelList = Arrays.asList(camelStrings.split(",")); camelList.stream().forEach(i -> System.out.println(CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, i) + ", "));