使用stream.collect(Collectors.joining(", "))
,我可以轻松地将流中的所有字符串用逗号分隔符连接起来。 可能的结果是"a, b, c"
。但是,如果我想将最后一个分隔符更改为不同的内容呢?例如,将其改为" and "
,以便获得"a, b and c"
作为结果。 是否有简单的解决方案?
使用stream.collect(Collectors.joining(", "))
,我可以轻松地将流中的所有字符串用逗号分隔符连接起来。 可能的结果是"a, b, c"
。但是,如果我想将最后一个分隔符更改为不同的内容呢?例如,将其改为" and "
,以便获得"a, b and c"
作为结果。 是否有简单的解决方案?
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));
};
}
Collector.<String,List<String>,String>of(
- Andreasjavac
没有给我编译错误,但我可以添加显式类型。使用的是哪个版本的Eclipse? - David ConradCollectors.collectingAndThen(Collectors.toList(), list -> { ... })
。 顺便说一下,您还可以使用 String.join(lastDelimiter, String.join(delimiter, list.subList(0, last)), list.get(last))
作为返回语句。 - HolgerjoiningLastDelimiter()
和 joiningOxfordComma()
两种解决方案,它们对于空列表和只有一个元素的列表都可以正常工作。只有第一种解决方案需要为这些情况添加保护条件。 - David ConradMyClass::joining...
作为“finisher”参数的参考)。 - Joshua Goldberg 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
stream.collect(Collectors.joining(" and "))
连接最后两个字符串。stream.collect(Collectors.joining(", "))
。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
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(", "));
这不是一个Streams-API的解决方案,但速度相当快。享受吧!
public static final <E> String join(
Iterable<E> objects, String separator, String lastSeparator)
{
Objects.requireNonNull(objects);
final String sep = separator == null ? "" : separator;
final String lastSep = lastSeparator == null ? sep : lastSeparator;
final StringBuilder builder = new StringBuilder();
final Iterator<E> iterator = objects.iterator();
while (iterator.hasNext()) {
final E next = iterator.next();
if (builder.length() > 0) {
if (iterator.hasNext()) {
builder.append(sep);
}
else {
builder.append(lastSep);
}
}
builder.append(next);
}
return builder.toString();
}
Collectors.joining
使用了一些非常笨拙的技巧,当你尝试做类似的事情时,它们会完全崩溃。 - Louis WassermanCollector
。至于“容易”,那就取决于技能和观点。 - Andreas", "
和", and "
。(我也喜欢用它。) - David Conrad