您可以使用StreamEx库在单个流管道中完成此操作。
List<Container> containersList = Arrays.asList(new Container("A"), new Container("B"), new Container("A"), new Container("A"), new Container("B"));
String[] result =
StreamEx.of(containersList)
.map(Container::getLetter)
.groupRuns(Object::equals)
.collect(MoreCollectors.pairing(
MoreCollectors.flatMapping(List::stream, Collectors.joining()),
MoreCollectors.mapping(l -> l.get(0), Collectors.joining()),
(s1, s2) -> new String[] { s1, s2 }
));
System.out.println(result[0]);
System.out.println(result[1]);
这段代码创建了一个容器的流,并将每个容器映射到它们的字母上。
然后,方法“groupRuns”将匹配给定谓词的连续元素折叠成一个List。在这种情况下,谓词是字符串的相等性:因此,如果您从流[ A,A,B ]开始,则此方法将其折叠成流[ List(A, A),List(B)](第一个元素是输入中2个A连续元素的列表)。
最后,使用“pairing”收集器将结果收集到两种不同的收集器中。第一个收集器将每个列表的平面图结果连接在一起,而第二个收集器仅连接列表的第一个元素(因此删除连续的元素)。
结果存储在一个数组中,该数组只作为两个值的持有者。
输出:
ABAAB
ABAB
直接使用Stream API
如果您想继续使用当前的API而不使用库,最好的方法是编写自定义Collector
:
public static void main(String[] args) {
List<Container> containersList = Arrays.asList(new Container("A"), new Container("B"), new Container("A"), new Container("A"), new Container("B"));
String[] result = containersList.stream().parallel().map(Container::getLetter).collect(ContainerCollector.collector());
System.out.println(result[0]);
System.out.println(result[1]);
}
private static final class ContainerCollector {
private StringBuilder text = new StringBuilder();
private StringBuilder dupText = new StringBuilder();
private void accept(String letter) {
text.append(letter);
if (dupText.indexOf(letter, dupText.length() - letter.length()) < 0) {
dupText.append(letter);
}
}
private ContainerCollector combine(ContainerCollector other) {
text.append(other.text);
other.dupText.codePoints().forEach(i -> {
String letter = new String(Character.toChars(i));
if (dupText.indexOf(letter, dupText.length() - letter.length()) < 0) {
dupText.append(letter);
}
});
return this;
}
private String[] finish() {
return new String[] { text.toString(), dupText.toString() };
}
private static Collector<String, ?, String[]> collector() {
return Collector.of(ContainerCollector::new, ContainerCollector::accept, ContainerCollector::combine, ContainerCollector::finish);
}
}
这个自定义收集器在每个字母被接受时构建
text
和
dupText
。对于
text
字符串,字母总是被追加。对于
dupText
,只有当最后一个字符不同时才会追加该字符。
组合器代码(在并行执行的情况下运行)对于
dupText
有些棘手:如果第二个字符串不以第一个字符串的结尾开始,则追加第二个字符串。否则,删除第一个字母并追加其余部分。
输出结果相同。
if(condition == false)
这样的语句。使用逻辑非符号,即“!”运算符来表示布尔型的规范否定形式:if(!condition)
,就像您写if(condition)
而不是if(condition==true)
一样,是吗?* 没错,是吗?* - Holger(condition==true)==true
以保持一致性吗?毕竟,condition==true
也是 一种条件。哦等等……(condition==true)==true
也是一种条件……你可以写a!=b
吗?还是必须写(a==b)==false
? - Holger