选项1:过滤
predicate – a 07001, 07002 predicate to apply to each element to determine if it should be included
public class NoRepeatFilter implements Predicate {
private T prevValue;
@Override
public boolean test(T value) {
if (value.equals(this.prevValue))
return false;
this.prevValue = value;
return true;
}
}
测试
List result = Stream
.of("A", "A", "A", "B", "B", "A", "A", "A", "C", "C", "C", "A", "A", "B", "B", "A")
// .parallel()
.filter(new NoRepeatFilter<>())
.collect(Collectors.toList());
System.out.println(result);
产量
[A,B,A,C,A,B,A]
它必须是无状态的原因是如果流是并行的,它将失败,例如,使用.parallel()再次运行测试取消注释:
[A,A,B,B,A,C,C,C,A,B,B,A]
选项2:收集者
一个有效的解决方案是使用of(...)创建自己的Collector:
public class NoRepeatCollector {
public static Collector> get() {
return Collector.of(ArrayList::new,
NoRepeatCollector::addNoRepeat,
NoRepeatCollector::combineNoRepeat);
}
private static void addNoRepeat(List list, E value) {
if (list.isEmpty() || ! list.get(list.size() - 1).equals(value))
list.add(value);
}
private static List combineNoRepeat(List left, List right) {
if (left.isEmpty())
return right;
if (! right.isEmpty())
left.addAll(left.get(left.size() - 1).equals(right.get(0))
? right.subList(1, right.size()) : right);
return left;
}
}
测试
List result = Stream
.of("A", "A", "A", "B", "B", "A", "A", "A", "C", "C", "C", "A", "A", "B", "B", "A")
// .parallel()
.collect(NoRepeatCollector.get());
System.out.println(result);
输出(有和没有.parallel())
[A,B,A,C,A,B,A]
选项3:循环
如果输入是List(或其他Iterable),则可以使用简单循环删除重复值:
public static void removeRepeats(Iterable iterable) {
E prevValue = null;
for (Iterator iter = iterable.iterator(); iter.hasNext(); ) {
E value = iter.next();
if (value.equals(prevValue))
iter.remove();
else
prevValue = value;
}
}
测试
List list = new ArrayList<>(Arrays.asList(
"A", "A", "A", "B", "B", "A", "A", "A", "C", "C", "C", "A", "A", "B", "B", "A"));
removeRepeats(list);
System.out.println(list);
产量
[A,B,A,C,A,B,A]