wake-up-neo.net

Eine Methode, um den Effekt von Java String.split () umzukehren?

Ich suche nach einer Methode, um ein Array von Strings in einem begrenzten String zusammenzufassen. Ein Gegenteil von split ().

Wollte das Forum fragen, bevor ich versuche, mein eigenes zu schreiben (da das JDK alles hat)

121
javaphild

Es gibt keine Methode in der JDK, die mir bekannt ist. Apache Commons Lang hat verschiedene überladene join()-Methoden in der StringUtils -Klasse, die tun, was Sie wollen.

90
John Topley

Seit mindestens 2009 gibt es eine Anforderung für ein offenes Feature. Die lange und kurze davon ist, dass sie Teil der Funktionalität der Java.util.StringJoiner-Klasse von JDK 8 ist. http://download.Java.net/lambda/b81/docs/api/Java/util/StringJoiner.html

Hier ist das Oracle-Problem, wenn Sie interessiert sind . http://bugs.Sun.com/view_bug.do?bug_id=5015163

Aktualisieren

Hier ist ein Beispiel für den neuen JDK 8 StringJoiner in einem String-Array

String[] a = new String[]{"first","second","third"};
StringJoiner sj = new StringJoiner(",");
for(String s:a) sj.add(s);
System.out.println(sj); //first,second,third

Eine Utility-Methode in String macht dies noch einfacher:

String s = String.join(",", stringArray);
39

Sie können diese Funktion aus dem Arrays-Hilfsprogramm herausschleichen.

import Java.util.Arrays;
...
    String  delim = ":",
            csv_record = "Field0:Field1:Field2", 
            fields[] = csv_record.split(delim);

    String rebuilt_record = Arrays.toString(fields).replace(", ", delim).replaceAll("[\\[\\]]", "");
22
David Howard

Ich habe folgendes Beispiel hier

/*
7) Join Strings using separator >>>AB$#$CD$#$EF

 */

import org.Apache.commons.lang.StringUtils;

public class StringUtilsTrial {
  public static void main(String[] args) {

    // Join all Strings in the Array into a Single String, separated by $#$
    System.out.println("7) Join Strings using separator >>>"
        + StringUtils.join(new String[] { "AB", "CD", "EF" }, "$#$"));
  }
}
16
Azder

Google stellt in seiner Google Collections-Bibliothek auch eine Joiner-Klasse bereit:

Joiner-API

Google Collections

12
Blair Zajac

Es gibt mehrere Beispiele für DZone-Snippets , wenn Sie Ihre eigenen Rollen ausführen möchten, die mit einer Collection funktionieren. Zum Beispiel:

public static String join(AbstractCollection<String> s, String delimiter) {
    if (s == null || s.isEmpty()) return "";
    Iterator<String> iter = s.iterator();
    StringBuilder builder = new StringBuilder(iter.next());
    while( iter.hasNext() )
    {
        builder.append(delimiter).append(iter.next());
    }
    return builder.toString();
}
10
Bill the Lizard

Wenn Sie ein int [] haben, ist Arrays.toString() der einfachste Weg.

7
DenTheMan

Basierend auf allen vorherigen Antworten:

public static String join(Iterable<? extends Object> elements, CharSequence separator) 
{
    StringBuilder builder = new StringBuilder();

    if (elements != null)
    {
        Iterator<? extends Object> iter = elements.iterator();
        if(iter.hasNext())
        {
            builder.append( String.valueOf( iter.next() ) );
            while(iter.hasNext())
            {
                builder
                    .append( separator )
                    .append( String.valueOf( iter.next() ) );
            }
        }
    }

    return builder.toString();
}
4
Sarabjot

Für Android: in Android.text.TextUtils Gibt es Methoden:

public static String join (CharSequence delimiter, Iterable tokens)
public static String join (CharSequence delimiter, Object[] tokens)

Gibt eine Zeichenfolge zurück, die die Token enthält, die mit Trennzeichen verbunden sind.

tokens - ein Array-Objekt, das verbunden werden soll. Zeichenfolgen werden aus den Objekten gebildet, indem object.toString () aufgerufen wird.

Dieser ist auch nicht schlecht:

public static String join(String delimitor,String ... subkeys) {
    String result = null;
    if(null!=subkeys && subkeys.length>0) {
        StringBuffer joinBuffer = new StringBuffer(subkeys[0]);
        for(int idx=1;idx<subkeys.length;idx++) {
            joinBuffer.append(delimitor).append(subkeys[idx]);
        }
        result = joinBuffer.toString();
    }
    return result;
}
1
Microscotch

Seit JDK8 liebe ich Streams und Lambdas sehr, daher würde ich vorschlagen:

public static String join( String delimiter, String[] array )
{
    return Arrays.asList( array ).stream().collect( Collectors.joining( delimiter ) );
}
1
Radouxca

Der Vollständigkeit halber möchte ich hinzufügen, dass Sie String # split generell nicht umkehren können, da ein regulärer Ausdruck akzeptiert wird.

"hello__world".split("_+"); ergibt ["hello", "world"].
"hello_world".split("_+"); Erträge ["hello", "world"]

Diese ergeben identische Ergebnisse von einem anderen Ausgangspunkt. Das Aufteilen ist keine Eins-zu-Eins-Operation und daher nicht umkehrbar.

Wenn Sie davon ausgehen, dass Ihr Parameter eine feste Zeichenfolge und keine reguläre Ausdrücke ist, können Sie dies sicherlich mit einer der zahlreichen Antworten tun.

1
Cruncher

Ich habe dieses geschrieben:

public static String join(Collection<String> col, String delim) {
    StringBuilder sb = new StringBuilder();
    Iterator<String> iter = col.iterator();
    if (iter.hasNext())
        sb.append(iter.next());
    while (iter.hasNext()) {
        sb.append(delim);
        sb.append(iter.next());
    }
    return sb.toString();
}

Collection wird nicht von JSP unterstützt, also schrieb ich für TLD:

public static String join(List<?> list, String delim) {
    int len = list.size();
    if (len == 0)
        return "";
    StringBuilder sb = new StringBuilder(list.get(0).toString());
    for (int i = 1; i < len; i++) {
        sb.append(delim);
        sb.append(list.get(i).toString());
    }
    return sb.toString();
}

und in .tld datei ablegen:

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://Java.Sun.com/xml/ns/javaee"
    <function>
        <name>join</name>
        <function-class>com.core.util.ReportUtil</function-class>
        <function-signature>Java.lang.String join(Java.util.List, Java.lang.String)</function-signature>
    </function>
</taglib>

und verwenden Sie es in JSP-Dateien als:

<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}
1
gavenkoa

Der folgende Code gibt eine grundlegende Idee. Dies ist jedoch nicht die beste Lösung.

public static String splitJoin(String sourceStr, String delim,boolean trim,boolean ignoreEmpty){
    return join(Arrays.asList(sourceStr.split(delim)), delim, ignoreEmpty);
}


public static String join(List<?> list, String delim, boolean ignoreEmpty) {
    int len = list.size();
    if (len == 0)
        return "";
    StringBuilder sb = new StringBuilder(list.get(0).toString());
    for (int i = 1; i < len; i++) {
        if (ignoreEmpty && !StringUtils.isBlank(list.get(i).toString())) {
            sb.append(delim);
            sb.append(list.get(i).toString().trim());
        }
    }
    return sb.toString();
}
1

Ich mag das besser:

public String join(Collection<String> strCollection, String delimiter) {
    String joined = "";
    int noOfItems = 0;
    for (String item : strCollection) {
        joined += item;
        if (++noOfItems < strCollection.size())
            joined += delimiter;
    }
    return joined;
}

Es ist die sauberste Lösung, die ich bisher gefunden habe ... (Machen Sie sich keine Sorgen über die Verwendung von rohen String-Objekten anstelle von StringBuilder. Moderne Java-Compiler verwenden trotzdem StringBuilder, aber dieser Code ist lesbarer).

0
Luis

Wenn Sie jdk8 verwenden, lesen Sie @Nathaniel Johnson Answer , da dies besser ist.

Ich denke, dass viele der Antworten hier komplex sind oder nicht leicht zu lesen sind. Bei so effizienter Verzweigungsvorhersage verwenden Sie einfach keine if-Anweisung.

public static String join(List<String> fooList){

    if (fooList.isEmpty()) return "";

    StringBuilder sb = null;

    for (String element : fooList) {

        if (sb == null) {
            sb = new StringBuilder();
        } else {
            sb.append(", ");
        }

        sb.append(element);
    }
    return sb.toString();
}

Es sollte erwähnt werden, dass Apache eine einfache for-Schleife mit einer if -Anweisung wie dieser verwendet (er verwendet ein Array als Index, um das erste Element zu kennen) und openjdk 8 dasselbe, jedoch in getrennten Methodenaufrufen anstelle von einfache Schleife.

0
PhoneixS