首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何删除List<T> JAVA 8中的重复

如何删除List<T> JAVA 8中的重复
EN

Stack Overflow用户
提问于 2018-03-10 19:23:41
回答 6查看 7.6K关注 0票数 6

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

假设我们在列表中有一个对象

A, A, A, B, B, A, A, A, C, C, C, A, A, B, B, A

现在我需要

A, B, A, C, A, B, A

因此,复制被移除,但只有在显示为next时才会删除,但是如果next是不同的对象,则应该保持不变。我尝试了一些解决方案,但软件很难看,而且无法读懂。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2018-03-10 20:11:18

选项1:过滤器

您可以编写有状态筛选器,但是不应该这样做,因为它违反了filter(Predicate predicate)的约定。

predicate -一个非干扰无国籍谓词,用于应用于每个元素,以确定是否应该包含它。

代码语言:javascript
复制
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;
    }
}

测试

代码语言:javascript
复制
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(...)

代码语言:javascript
复制
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;
    }
}

测试

代码语言:javascript
复制
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),则可以使用简单的循环删除重复值:

代码语言:javascript
复制
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;
    }
}

测试

代码语言:javascript
复制
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]

票数 13
EN

Stack Overflow用户

发布于 2018-03-10 19:38:35

它很简单,不用流。就像这样:

代码语言:javascript
复制
public List<T> noConsecutiveDuplicates(final List<T> input) {   
    final List<T> output = new ArrayList<>();
    for (final T element : input) {
        if (!element.equals(lastElement(output))) {
            output.add(element);
        }
    }
    return output;
}    

private T lastElement(final List<T> list) {
    if (list.size() == 0) {
        return null;
    }
    return list.get(list.size() - 1);
}
票数 1
EN

Stack Overflow用户

发布于 2018-03-11 18:31:15

我会给StreamEx一次机会使用StreamEx::collapse

代码语言:javascript
复制
List<String> strings = Arrays.asList("A", "A", "A", "B", "B", "A", "A", "A", "C", "C", "C", "A", "A", "B", "B", "A");

List<String> collect = StreamEx.of(strings)
        .collapse(Objects::equals)
        .collect(Collectors.toList());

使用vanilla并利用“边缘检测”的思想也是可能的。

代码语言:javascript
复制
List<String> collect = IntStream.range(0, strings.size())
        .filter(i -> i == 0 || !Objects.equals(strings.get(i - 1), strings.get(i)))
        .mapToObj(strings::get)
        .collect(Collectors.toList());
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49213102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档