在 Java 中构建一串分隔项的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/63150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:50:08  来源:igfitidea点击:

What's the best way to build a string of delimited items in Java?

javastringalgorithm

提问by Sean McMains

While working in a Java app, I recently needed to assemble a comma-delimited list of values to pass to another web service without knowing how many elements there would be in advance. The best I could come up with off the top of my head was something like this:

在 Java 应用程序中工作时,我最近需要组合一个以逗号分隔的值列表以传递给另一个 Web 服务,而无需事先知道有多少元素。我能想到的最好的东西是这样的:

public String appendWithDelimiter( String original, String addition, String delimiter ) {
    if ( original.equals( "" ) ) {
        return addition;
    } else {
        return original + delimiter + addition;
    }
}

String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );

I realize this isn't particularly efficient, since there are strings being created all over the place, but I was going for clarity more than optimization.

我意识到这不是特别有效,因为到处都在创建字符串,但我比优化更要清晰。

In Ruby, I can do something like this instead, which feels much more elegant:

在 Ruby 中,我可以做这样的事情,感觉更优雅:

parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");

But since Java lacks a join command, I couldn't figure out anything equivalent.

但是由于 Java 缺少 join 命令,我无法找出任何等效的东西。

So, what's the best way to do this in Java?

那么,在 Java 中执行此操作的最佳方法是什么?

采纳答案by Martin Gladdish

Pre Java 8:

Java 8 之前:

Apache's commons lang is your friend here - it provides a join method very similar to the one you refer to in Ruby:

Apache 的 commons lang 是您的朋友 - 它提供了一种与您在 Ruby 中引用的非常相似的连接方法:

StringUtils.join(java.lang.Iterable,char)

StringUtils.join(java.lang.Iterable,char)



Java 8:

爪哇 8:

Java 8 provides joining out of the box via StringJoinerand String.join(). The snippets below show how you can use them:

Java 8 通过StringJoiner和提供开箱即用的连接String.join()。下面的片段展示了如何使用它们:

StringJoiner

StringJoiner

StringJoiner joiner = new StringJoiner(",");
joiner.add("01").add("02").add("03");
String joinedString = joiner.toString(); // "01,02,03"


String.join(CharSequence delimiter, CharSequence... elements))

String.join(CharSequence delimiter, CharSequence... elements))

String joinedString = String.join(" - ", "04", "05", "06"); // "04 - 05 - 06"


String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

List<String> strings = new LinkedList<>();
strings.add("Java");strings.add("is");
strings.add("cool");
String message = String.join(" ", strings);
//message returned is: "Java is cool"

回答by Stu Thompson

Use an approach based on java.lang.StringBuilder! ("A mutable sequence of characters. ")

使用基于java.lang.StringBuilder! (“一个可变的字符序列。”)

Like you mentioned, all those string concatenations are creating Strings all over. StringBuilderwon't do that.

就像你提到的,所有这些字符串连接都在创建字符串。 StringBuilder不会那样做。

Why StringBuilderinstead of StringBuffer? From the StringBuilderjavadoc:

为什么StringBuilder而不是StringBuffer?从StringBuilderjavadoc:

Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

在可能的情况下,建议优先使用此类而不是 StringBuffer,因为在大多数实现下它会更快。

回答by Kent Boogaart

You can use Java's StringBuildertype for this. There's also StringBuffer, but it contains extra thread safety logic that is often unnecessary.

您可以StringBuilder为此使用 Java 的类型。还有StringBuffer,但它包含通常不必要的额外线程安全逻辑。

回答by Dave Costa

Why not write your own join() method? It would take as parameters collection of Strings and a delimiter String. Within the method iterate over the collection and build up your result in a StringBuffer.

为什么不编写自己的 join() 方法?它将作为参数集合的字符串和分隔符字符串。在该方法中迭代集合并在 StringBuffer 中构建您的结果。

回答by Vinko Vrsalovic

You can generalize it, but there's no join in Java, as you well say.

您可以对其进行概括,但正如您所说,Java 中没有连接。

Thismight work better.

可能效果更好。

public static String join(Iterable<? extends CharSequence> s, String delimiter) {
    Iterator<? extends CharSequence> iter = s.iterator();
    if (!iter.hasNext()) return "";
    StringBuilder buffer = new StringBuilder(iter.next());
    while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
    return buffer.toString();
}

回答by martinatime

You can try something like this:

你可以尝试这样的事情:

StringBuilder sb = new StringBuilder();
if (condition) { sb.append("elementName").append(","); }
if (anotherCondition) { sb.append("anotherElementName").append(","); }
String parameterString = sb.toString();

回答by izb

public static String join(String[] strings, char del)
{
    StringBuffer sb = new StringBuffer();
    int len = strings.length;
    boolean appended = false;
    for (int i = 0; i < len; i++)
    {
        if (appended)
        {
            sb.append(del);
        }
        sb.append(""+strings[i]);
        appended = true;
    }
    return sb.toString();
}

回答by newdayrising

You should probably use a StringBuilderwith the appendmethod to construct your result, but otherwise this is as good of a solution as Java has to offer.

您可能应该使用StringBuilderwithappend方法来构建您的结果,但除此之外,这与 Java 所提供的解决方案一样好。

回答by agnul

Why don't you do in Java the same thing you are doing in ruby, that is creating the delimiter separated string only after you've added all the pieces to the array?

为什么不在 Java 中做与在 ruby​​ 中所做的相同的事情,即仅在将所有部分添加到数组后才创建分隔符分隔的字符串?

ArrayList<String> parms = new ArrayList<String>();
if (someCondition) parms.add("someString");
if (anotherCondition) parms.add("someOtherString");
// ...
String sep = ""; StringBuffer b = new StringBuffer();
for (String p: parms) {
    b.append(sep);
    b.append(p);
    sep = "yourDelimiter";
}

You may want to move that for loop in a separate helper method, and also use StringBuilder instead of StringBuffer...

您可能希望在单独的辅助方法中移动该 for 循环,并且还使用 StringBuilder 而不是 StringBuffer ...

Edit: fixed the order of appends.

编辑:修复了追加的顺序。

回答by Rob Dickerson

You could write a little join-style utility method that works on java.util.Lists

您可以编写一个适用于 java.util.Lists 的连接样式实用方法

public static String join(List<String> list, String delim) {

    StringBuilder sb = new StringBuilder();

    String loopDelim = "";

    for(String s : list) {

        sb.append(loopDelim);
        sb.append(s);            

        loopDelim = delim;
    }

    return sb.toString();
}

Then use it like so:

然后像这样使用它:

    List<String> list = new ArrayList<String>();

    if( condition )        list.add("elementName");
    if( anotherCondition ) list.add("anotherElementName");

    join(list, ",");