gpt4 book ai didi

java - 如何在List JAVA 8中删除重复项

转载 作者:行者123 更新时间:2023-12-04 13:25:41 26 4
gpt4 key购买 nike

实际上,我知道减少重复的distinct()或将List分配给Set的方法,但是我有一些不同的问题。
如何使用流或可能是StreamEx的JAVA 8问题以下解决聪明的方法?

假设我们在List中有一个对象
A, A, A, B, B, A, A, A, C, C, C, A, A, B, B, A
现在我需要
A, B, A, C, A, B, A
因此,已删除重复项,但只有当下一个出现时才被删除,但如果下一个是另一个对象,则应保留。
我尝试了一些解决方案,但感觉很丑陋,而且不可读。

最佳答案

选项1:过滤器

您可以编写一个有状态的过滤器,但是绝对不要执行该,因为它违反了 filter(Predicate<? super T> predicate) 的约定:

predicate - a non-interfering, stateless predicate to apply to each element to determine if it should be included


public class NoRepeatFilter<T> implements Predicate<T> {
private T prevValue;
@Override
public boolean test(T value) {
if (value.equals(this.prevValue))
return false;
this.prevValue = value;
return true;
}
}

测试
List<String> 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:收集器

一个有效的解决方案是使用 Collector 创建自己的 of(...) :
public class NoRepeatCollector {
public static <E> Collector<E, ?, List<E>> get() {
return Collector.of(ArrayList::new,
NoRepeatCollector::addNoRepeat,
NoRepeatCollector::combineNoRepeat);
}
private static <E> void addNoRepeat(List<E> list, E value) {
if (list.isEmpty() || ! list.get(list.size() - 1).equals(value))
list.add(value);
}
private static <E> List<E> combineNoRepeat(List<E> left, List<E> 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<String> 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 <E> void removeRepeats(Iterable<E> iterable) {
E prevValue = null;
for (Iterator<E> iter = iterable.iterator(); iter.hasNext(); ) {
E value = iter.next();
if (value.equals(prevValue))
iter.remove();
else
prevValue = value;
}
}

测试
List<String> 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]

关于java - 如何在List <T> JAVA 8中删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49213102/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com