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