【问题标题】:Removing duplicates from list with additional condition使用附加条件从列表中删除重复项
【发布时间】:2018-03-29 19:19:41
【问题描述】:

我面临着相当复杂的任务(至少对我而言)。假设我们有List<E>,E 有两个字段A 和B。列表可能有重复项。我们需要删除与A 字段重复的E 实例,并留下具有最​​多B 的实例(假设我们可以像一些原始类型一样比较它)。
示例:
输入: [{1; 1}, {1; 2}, {3; 4}, {3; 3}, {3; 1}, {2; 2}]
输出: [{1; 2}, {3; 4}, {2; 2}]
我想到的第一件事就是使用嵌套的for 循环,比如this。但首先我不确定在循环内删除列表节点是否会正常工作。其次,最好不要让内部for 迭代整个列表,而是从外部迭代器到列表末尾,在这种情况下,我们可能会发现外部迭代器比内部迭代器“小”,所以我们需要删除它,我再次不确定它是否会损害循环。
所以我的问题简而言之是:我们是否能够使用for 循环编写可靠的代码,您将如何实现它,或者您更喜欢什么其他设计。

【问题讨论】:

    标签: java list loops iterator


    【解决方案1】:

    我今天学到的关于列表的一件事是,如果您想删除一个项目,则向后迭代列表。这样可以避免 indexoutofrange 异常。 否则我会用for循环来做,没有更好的主意。

    【讨论】:

    • 你能提供一些实现吗?对我来说,我将如何使用嵌套 for 向后迭代并不明显。我应该为此创建自定义迭代器吗?
    【解决方案2】:

    我会使用流。让我们从一些虚拟类型定义开始:

    interface E {
        A getA();
        B getB();
    }
    
    interface A {}
    
    interface B extends Comparable<B> {}
    

    现在假设你有一些List&lt;E&gt; list。您可以流式传输和收集最大 B 的元素,按 A 分组,然后只需抓取地图的值:

    Collection<E> maxB = list.stream()
            .collect(Collectors.groupingBy(E::getA,
                    Collectors.collectingAndThen(
                            Collectors.maxBy(Comparator.comparing(E::getB)),
                            Optional::get)))
            .values();
    

    【讨论】:

    • 哇!经过 6 个月的 Java,我仍然不使用流。肯定会深入研究它,因为它提供了如此广泛的功能。
    • @Russiancold 是的,流很棒!肯定有一个学习曲线,但您不会后悔投资。
    猜你喜欢
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 2012-08-27
    相关资源
    最近更新 更多