使用逗号和"和"将Java中的List <String>连接起来

sli*_*set 49 java join apache-commons

给出一个清单

List<String> l = new ArrayList<String>();
l.add("one");
l.add("two");
l.add("three");
Run Code Online (Sandbox Code Playgroud)

我有一个方法

String join(List<String> messages) {
        if (messages.isEmpty()) return "";
        if (messages.size() == 1) return messages.get(0);
        String message = "";
        message = StringUtils.join(messages.subList(0, messages.size() -2), ", ");
        message = message + (messages.size() > 2 ? ", " : "") + StringUtils.join(messages.subList(messages.size() -2, messages.size()), ", and ");
        return message;
    }
Run Code Online (Sandbox Code Playgroud)

对于l,产生"一,二,三".我的问题是,是否有一个标准(apache-commons)方法做同样的事情,例如

WhatEverUtils.join(l, ", ", ", and ");
Run Code Online (Sandbox Code Playgroud)

澄清.我的问题是没有让这种方法起作用.它就像我想要的那样工作,经过测试,一切都很好.我的问题是我找不到一些实现这种功能的类似apache-commons的模块.这让我感到惊讶,因为我不能成为第一个需要这个的人.

但是,也许其他人都刚刚完成了

StringUtils.join(l, ", ").replaceAll(lastCommaRegex, ", and");
Run Code Online (Sandbox Code Playgroud)

Ali*_*ani 56

在Java 8中,您可以使用String.join()以下内容:

Collection<String> elements = ....;
String result = String.join(", ", elements);
Run Code Online (Sandbox Code Playgroud)


luk*_*ymo 17

关于什么加入来自: org.apache.commons.lang.StringUtils

例:

StringUtils.join(new String[] { "one", "two", "three" }, ", "); // one, two, three
Run Code Online (Sandbox Code Playgroud)

要拥有"和"或",和",您可以简单地替换最后一个逗号.

  • 这并没有按照OP的要求产生“一、二、三”。观察:他在问题中使用了“join”方法 (4认同)

Jac*_*erk 14

我喜欢使用谷歌收藏品.整洁,非常有用:

Joiner.on(",").join(myList)
Run Code Online (Sandbox Code Playgroud)

这种代码已经一次又一次地编写,您应该释放实现您的特定实现逻辑.

如果你使用maven,那么依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.1-jre</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

它还有许多其他很酷的功能!

编辑:为了完整起见,这将产生"一,二,三"列表.

List<String> originalList = Arrays.asList("one", "two", "three");
Joiner.on(", ")
    .join(originalList.subList(0, originalList.size() - 1))
    .concat(", and ")
    .concat(originalList.get(originalList.size() - 1));
Run Code Online (Sandbox Code Playgroud)

  • -1如果只有一个元素,则会产生`"和一个"`,"一个". (2认同)

Cpp*_*oob 13

使用Java 8,您可以将流与加入者一起使用.

Collection<String> strings;
...
String commaDelimited = strings.stream().collect(Collectors.joining(","));
// use strings.parallelStream() instead, if you think
//   there are gains to be had by doing fork/join
Run Code Online (Sandbox Code Playgroud)


Boh*_*ian 5

其他答案谈到“替换最后一个逗号”,如果最后一个术语本身包含一个逗号,这是不安全的。

您可以只使用一行(虽然很长)JDK 代码,而不是使用库:

public static String join(List<String> msgs) {
    return msgs == null || msgs.size() == 0 ? "" : msgs.size() == 1 ? msgs.get(0) : msgs.subList(0, msgs.size() - 1).toString().replaceAll("^.|.$", "") + " and " + msgs.get(msgs.size() - 1);
}
Run Code Online (Sandbox Code Playgroud)

查看此代码处理所有边缘情况的现场演示


仅供参考,这是一个更具可读性的两行:

public static String join(List<String> msgs) {
    int size = msgs == null ? 0 : msgs.size();
    return size == 0 ? "" : size == 1 ? msgs.get(0) : msgs.subList(0, --size).toString().replaceAll("^.|.$", "") + " and " + msgs.get(size);
}
Run Code Online (Sandbox Code Playgroud)


Abt*_*ian 5

为了产生英语的语法输出,在连接字符串列表时需要考虑 3 种情况:

  1. “一种”

  2. “A和B”

  3. “A、B、C。

这可以使用标准 Java 或 Guava 来完成,如下所示。解决方案基本相同,仅取决于您想要使用的偏好。

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;

import org.junit.Test;

import java.util.List;

import static org.junit.Assert.assertEquals;

public class JoinListTest {

    @Test
    public void test_join() {
        // create cases (don't need to use ImmutableList builder from guava)
        final List<String> case1 = new ImmutableList.Builder<String>().add("A").build();
        final List<String> case2 = new ImmutableList.Builder<String>().add("A", "B").build();
        final List<String> case3 = new ImmutableList.Builder<String>().add("A", "B", "C").build();
        // test with standard java
        assertEquals("A", joinListGrammaticallyWithJava(case1));
        assertEquals("A and B", joinListGrammaticallyWithJava(case2));
        assertEquals("A, B, and C", joinListGrammaticallyWithJava(case3));
        // test with guava
        assertEquals("A", joinListGrammaticallyWithGuava(case1));
        assertEquals("A and B", joinListGrammaticallyWithGuava(case2));
        assertEquals("A, B, and C", joinListGrammaticallyWithGuava(case3));
    }

    private String joinListGrammaticallyWithJava(final List<String> list) {
        return list.size() > 1
                ? String.join(", ", list.subList(0, list.size() - 1))
                    .concat(String.format("%s and ", list.size() > 2 ? "," : ""))
                    .concat(list.get(list.size() - 1))
                : list.get(0);
    }

    private String joinListGrammaticallyWithGuava(final List<String> list) {
        return list.size() > 1
                ? Joiner.on(", ").join(list.subList(0, list.size() - 1))
                    .concat(String.format("%s and ", list.size() > 2 ? "," : ""))
                    .concat(list.get(list.size() - 1))
                : list.get(0);
    }

}
Run Code Online (Sandbox Code Playgroud)


Sat*_*hJM 0

如果您想要更全面的解决方案,可以使用一个出色的NLG库 - SimpleNLG

//initialize 
NLGFactory nlgFactory = new NLGFactory(Lexicon.getDefaultLexicon());
Realiser realiser = new Realiser(lexicon);
CoordinatedPhraseElement cp = nlgFactory.createCoordinatedPhrase();
cp.setConjunction("and");


//code begins here
List<String> l = new ArrayList<String>();
l.add("one");
l.add("two");
l.add("three");
l.forEach(cp::addCoordinate);


//output
String output = realiser.realise(cp).toString();
Run Code Online (Sandbox Code Playgroud)

这可以支持任意数量的数组元素,而无需执行诸如“删除最后一个逗号”之类的丑陋黑客行为。