加入具有不同最后分隔符的字符串

时间:2016-01-22 00:07:46

标签: java string java-8 java-stream

使用stream.collect(Collectors.joining(", "))我可以轻松地加入逗号分隔的流的所有字符串。可能的结果是"a, b, c"。但是,如果我希望最后一个分隔符不同,该怎么办呢?例如,为" and ",以便得到"a, b and c"作为结果。有一个简单的解决方案吗?

7 个答案:

答案 0 :(得分:7)

如果它们已经在列表中,则不需要流;只需加入除最后一个元素之外的所有子元素,并连接另一个分隔符和最后一个元素:

int last = list.size() - 1;
String joined = String.join(" and ",
                    String.join(", ", list.subList(0, last)),
                    list.get(last));

以下是使用Collectors.collectingAndThen:

执行上述操作的版本
stream.collect(Collectors.collectingAndThen(Collectors.toList(),
    joiningLastDelimiter(", ", " and ")));

public static Function<List<String>, String> joiningLastDelimiter(
        String delimiter, String lastDelimiter) {
    return list -> {
                int last = list.size() - 1;
                if (last < 1) return String.join(delimiter, list);
                return String.join(lastDelimiter,
                    String.join(delimiter, list.subList(0, last)),
                    list.get(last));
            };
}

此版本还可以处理流为空或只有一个值的情况。感谢Holger和Andreas提出的建议,这些建议大大改善了这一解决方案。

我在评论中建议牛津逗号可以使用", "", and"作为分隔符来完成,但是对于两个元素会产生"a, and b"的错误结果,所以只是为了好玩这里正确地使用牛津逗号:

stream.collect(Collectors.collectingAndThen(Collectors.toList(),
    joiningOxfordComma()));

public static Function<List<String>, String> joiningOxfordComma() {
    return list -> {
                int last = list.size() - 1;
                if (last < 1) return String.join("", list);
                if (last == 1) return String.join(" and ", list);
                return String.join(", and ",
                    String.join(", ", list.subList(0, last)),
                    list.get(last));
            };
}

答案 1 :(得分:5)

如果你对"a, b, and c"没问题,那么我可以使用mapLast库的StreamEx方法扩展标准Stream API并进行其他操作:

String result = StreamEx.of("a", "b", "c")
                        .mapLast("and "::concat)
                        .joining(", "); // "a, b, and c"

mapLast方法将给定映射应用于最后一个流元素,保持其他元素不变。我甚至有类似的unit-test

答案 2 :(得分:1)

首先尝试使用stream.collect(Collectors.joining(" and "))

加入最后两个字符串

然后使用您在问题中使用的代码加入所有剩余字符串和此新字符串:stream.collect(Collectors.joining(", "))

答案 3 :(得分:1)

如果您正在寻找旧Java解决方案,使用Guava libraries会很容易。

    List<String> values = Arrays.asList("a", "b", "c");
    String output = Joiner.on(",").join(values);
    output = output.substring(0, output.lastIndexOf(","))+" and "+values.get(values.size()-1);
    System.out.println(output);//a,b and c

答案 4 :(得分:0)

    List<String> names = Arrays.asList("Thomas", "Pierre", "Yussef", "Rick");
    int length = names.size();
    String result = IntStream.range(0, length - 1).mapToObj(i -> {
        if (i == length - 2) {
            return names.get(i) + " and " + names.get(length - 1);
        } else {
            return names.get(i);
        }
    }).collect(Collectors.joining(", "));

答案 5 :(得分:0)

这不是Streams-API解决方案,但速度非常快。享受吧!

function Car(model, color, price) {
  this.model = model;
  this.color = color;
  this.price = price;

  this.changeColor = function() {
    console.log(this);
    this.color = 'Blue';
  };

  this.getCar = function() {
    changeColor();
    return console.log(`Model: ${this.model} Color: ${this.color} Price: ${this.price}`);
  };
}

const mitsubishi = new Car('Mitsubishi', 'Black', 1991);

mitsubishi.getCar();

答案 6 :(得分:-1)

String str = "a , b , c , d";
String what_you_want = str.substring(0, str.lastIndexOf(","))
        + str.substring(str.lastIndexOf(",")).replace(",", "and");

// what_you_want is : a , b , c and d