Una manera rápida y fácil de unir elementos de la matriz con un separador (lo opuesto a la división) en Java

Ver preguntas relacionadas con .NET

Estoy buscando una manera rápida y fácil de hacer exactamente lo contrario de dividir para que ["a","b","c"] convierta en "a,b,c"

La iteración a través de una matriz requiere agregar una condición (si este no es el último elemento, agregar el separador) o usar una subcadena para eliminar el último separador.

Estoy seguro de que hay una forma certificada y eficiente de hacerlo (Apache Commons?)

¿Cómo prefieres hacerlo en tus proyectos?

Usando Java 8 puedes hacer esto de una manera muy limpia:

 String.join(delimiter, elements); 

Esto funciona de tres maneras:

1) especificando directamente los elementos

 String joined1 = String.join(",", "a", "b", "c"); 

2) usando arreglos

 String[] array = new String[] { "a", "b", "c" }; String joined2 = String.join(",", array); 

3) usando iterables

 List list = Arrays.asList(array); String joined3 = String.join(",", list); 

Si estás en Android puedes TextUtils.join(delimiter, tokens)

Prefiero Google Collections sobre Apache StringUtils para este problema en particular:

 Joiner.on(separator).join(array) 

Comparado con StringUtils, Joiner API tiene un diseño fluido y es un poco más flexible, por ejemplo, null elementos null pueden omitirse o reemplazarse por un marcador de posición. Además, Joiner tiene una función para unir mapas con un separador entre clave y valor.

Apache Commons Lang sí tiene un método StringUtils.join que conectará matrices de String junto con un separador especificado.

Por ejemplo:

 String[] s = new String[] {"a", "b", "c"}; String joined = StringUtils.join(s, ","); // "a,b,c" 

Sin embargo, sospecho que, como usted menciona, debe haber algún tipo de procesamiento condicional o de subcadena en la implementación real del método mencionado anteriormente.

Si tuviera que realizar la unión de String y no tuviera otras razones para usar Commons Lang, probablemente aplicaría las mías para reducir el número de dependencias a bibliotecas externas.

Una solución rápida y simple sin ningún tercero incluye.

 public static String strJoin(String[] aArr, String sSep) { StringBuilder sbStr = new StringBuilder(); for (int i = 0, il = aArr.length; i < il; i++) { if (i > 0) sbStr.append(sSep); sbStr.append(aArr[i]); } return sbStr.toString(); } 

“Estoy seguro de que hay una forma certificada y eficiente de hacerlo (Apache Commons?)”

sí, aparentemente es

 StringUtils.join(array, separator) 

http://www.java2s.com/Code/JavaAPI/org.apache.commons.lang/StringUtilsjoinObjectarrayStringseparator.htm

Aún más fácil puede usar Arrays, por lo que obtendrá un String con los valores de la matriz separados por un “,”

 String concat = Arrays.toString(myArray); 

así que terminarás con esto: concat = “[a, b, c]”

Actualizar

A continuación, puede deshacerse de los corchetes utilizando una subcadena según lo sugerido por Jeff

 concat = concat.substring(1, concat.length() -1); 

entonces terminas con concat = “a, b, c”

Puede usar replace y replaceAll con expresiones regulares.

 String[] strings = {"a", "b", "c"}; String result = Arrays.asList(strings).toString().replaceAll("(^\\[|\\]$)", "").replace(", ", ","); 

Como Arrays.asList().toString() produce: “[a, b, c]”, hacemos un replaceAll para eliminar los primeros y últimos corchetes y luego (opcionalmente) puede cambiar la secuencia “,” para “,” (su nuevo separador).

Una versión eliminada (menos caracteres):

 String[] strings = {"a", "b", "c"}; String result = ("" + Arrays.asList(strings)).replaceAll("(^.|.$)", "").replace(", ", "," ); 

Las expresiones regulares son muy potentes, especialmente los métodos String “replaceFirst” y “replaceAll”. Pruébalos.

Con Java 1.8 hay una nueva clase StringJoiner , por lo que no hay necesidad de Guava o Apache Commons:

 String str = new StringJoiner(",").add("a").add("b").add("c").toString(); 

O usando una colección directamente con la nueva API de transmisión:

 String str = Arrays.asList("a", "b", "c").stream().collect(Collectors.joining(",")); 

Todas estas otras respuestas incluyen sobrecarga en tiempo de ejecución … como usar ArrayList.toString (). ReplaceAll (…) que son muy derrochadores.

Le daré el algoritmo óptimo con cero gastos generales; no se ve tan bonito como las otras opciones, pero internamente, esto es lo que están haciendo todos (después de montones de otras comprobaciones ocultas, asignación de múltiples matrices y otro crud).

Como ya sabe que está tratando con cadenas, puede guardar un conjunto de asignaciones de matriz realizando todo manualmente. Esto no es bonito, pero si rastrea las llamadas al método real realizadas por las otras implementaciones, verá que tiene la menor sobrecarga de tiempo de ejecución posible.

 public static String join(String separator, String ... values) { if (values.length==0)return "";//need at least one element //all string operations use a new array, so minimize all calls possible char[] sep = separator.toCharArray(); // determine final size and normalize nulls int totalSize = (values.length - 1) * sep.length;// separator size for (int i = 0; i < values.length; i++) { if (values[i] == null) values[i] = ""; else totalSize += values[i].length(); } //exact size; no bounds checks or resizes char[] joined = new char[totalSize]; int pos = 0; //note, we are iterating all the elements except the last one for (int i = 0, end = values.length-1; i < end; i++) { System.arraycopy(values[i].toCharArray(), 0, joined, pos, values[i].length()); pos += values[i].length(); System.arraycopy(sep, 0, joined, pos, sep.length); pos += sep.length; } //now, add the last element; //this is why we checked values.length == 0 off the hop System.arraycopy(values[values.length-1].toCharArray(), 0, joined, pos, values[values.length-1].length()); return new String(joined); } 

Esta opción es rápida y clara:

  public static String join(String separator, String... values) { StringBuilder sb = new StringBuilder(128); int end = 0; for (String s : values) { if (s != null) { sb.append(s); end = sb.length(); sb.append(separator); } } return sb.substring(0, end); } 

Esta pequeña función siempre es útil.

 public static String join(String[] strings, int startIndex, String separator) { StringBuffer sb = new StringBuffer(); for (int i=startIndex; i < strings.length; i++) { if (i != startIndex) sb.append(separator); sb.append(strings[i]); } return sb.toString(); } 

El enfoque que he adoptado ha evolucionado desde Java 1.0 para proporcionar legibilidad y mantener opciones razonables para la compatibilidad con versiones anteriores de Java, al tiempo que proporciona firmas de métodos que son reemplazos para aquellos de apache commons-lang. Por razones de rendimiento, puedo ver algunas objeciones posibles al uso de Arrays.asList, pero prefiero los métodos de ayuda que tienen valores predeterminados razonables sin duplicar el único método que realiza el trabajo real. Este enfoque proporciona puntos de entrada apropiados a un método confiable que no requiere conversiones de matriz / lista antes de llamar.

Las posibles variaciones para la compatibilidad de la versión de Java incluyen la sustitución de StringBuffer (Java 1.0) por StringBuilder (Java 1.5), el cambio del iterador de Java 1.5 y la eliminación del comodín genérico (Java 1.5) de la Colección (Java 1.2). Si desea llevar la compatibilidad con versiones anteriores un paso o dos más, elimine los métodos que usan Colección y mueva la lógica al método basado en matrices.

 public static String join(String[] values) { return join(values, ','); } public static String join(String[] values, char delimiter) { return join(Arrays.asList(values), String.valueOf(delimiter)); } // To match Apache commons-lang: StringUtils.join(values, delimiter) public static String join(String[] values, String delimiter) { return join(Arrays.asList(values), delimiter); } public static String join(Collection values) { return join(values, ','); } public static String join(Collection values, char delimiter) { return join(values, String.valueOf(delimiter)); } public static String join(Collection values, String delimiter) { if (values == null) { return new String(); } StringBuffer strbuf = new StringBuffer(); boolean first = true; for (Object value : values) { if (!first) { strbuf.append(delimiter); } else { first = false; } strbuf.append(value.toString()); } return strbuf.toString(); } 
 public String join(String[] str, String separator){ String retval = ""; for (String s: str){ retval+= separator + s;} return retval.replaceFirst(separator, ""); }