【问题标题】:remove duplicate list from an arrayList using Set使用 Set 从 arrayList 中删除重复列表
【发布时间】:2019-05-04 05:06:08
【问题描述】:

我有一个包含重复 ArrayList 的列表。

我正在寻找删除它们的解决方案。

这是一个例子:

listOne = [[1, 0], [0, 1], [3, 2], [2, 3]]

此集合包含重复的列表。通常我想得到:

theListAfterTransformation  = [[1, 0],[3, 2]]

这是我的小例子,我尝试使用 Set 但效果不佳。

public class Example {
    public static void main( String[] args ) {
        ArrayList<ArrayList<Integer>> lists = new ArrayList<>();

        ArrayList<Integer> list1 = new ArrayList<>(); list1.add(1); list1.add(0);
        ArrayList<Integer> list2 = new ArrayList<>(); list2.add(0); list2.add(1);
        ArrayList<Integer> list3 = new ArrayList<>(); list3.add(3); list3.add(2);
        ArrayList<Integer> list4 = new ArrayList<>(); list4.add(2); list4.add(3);

        lists.add(list1);lists.add(list2);lists.add(list3);lists.add(list4);

        System.out.println(getUnduplicateList(lists));


    }
    public static ArrayList<ArrayList<Integer>> getUnduplicateList( ArrayList<ArrayList<Integer>> lists) {
        Iterator iterator = lists.iterator();
        Set<ArrayList<Integer>> set = new HashSet<>();
        while (iterator.hasNext()){
            ArrayList<Integer> list = (ArrayList<Integer>) iterator.next();
            set.add(list);
        }
        return new ArrayList<>(set);
    }

}

请注意,这是我项目中的一个小例子,在这个实现中使用改变很多事情的解决方案将非常困难。

所以要考虑到 getUnduplicateList 应该保持相同的签名。好主意是只更改实现。

此程序打印与输入相同的列表。请有任何想法。

【问题讨论】:

标签: java arraylist collections set


【解决方案1】:

关于术语的几点说明——Set 是与 List 不同的数据结构,前者是无序的,不允许重复,而后者是基本的线性集合,通常是有序的,并且允许重复.您似乎可以互换使用这些术语,这可能是您遇到的问题的一部分:Set 可能是这里合适的数据结构。

也就是说,您的代码似乎依赖于List API,因此我们可以继续跟进。请注意,您通常应该对接口 (List) 进行编码,而不是特定类(ArrayList)。

此外,考虑使用Arrays.asList 速记方法来初始化列表(注意这会返回一个不可变列表)。

最后,请注意HashSet 通过检查两个对象是否具有相同的hashCode 来消除重复项。除非元素出现在same order 中,否则包含相同元素的列表仍不被视为相同列表,并且通常不会被视为重复项。然而,集合实现 equalshashCode 的方式是,包含完全相同元素的两个集合被视为相等(顺序无关紧要)。


使用您的原始起始集合,您可以将每个内部列表转换为一个集合。然后,从外部集合中消除重复项。最后,将内部集合转换回列表,以保持与其余代码的兼容性(如果需要)。无论内部列表的大小如何,这种方法都可以使用。

您可以使用Stream 模拟这些步骤,并使用方法引用与Set 相互转换,如下所示。


import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.stream.Collectors;

public class Example {

    public static void main( String[] args ) {
        List<Integer> list1 = Arrays.asList(1, 0);
        List<Integer> list2 = Arrays.asList(0, 1);
        List<Integer> list3 = Arrays.asList(3, 2);
        List<Integer> list4 = Arrays.asList(2, 3);

        List<List<Integer>> lists = Arrays.asList(list1, list2, list3, list4);

        System.out.println(getUnduplicateList(lists));
    }

    public static List<List<Integer>> getUnduplicateList(List<List<Integer>> lists) {
        return lists
                .stream()
                .map(HashSet::new)
                .distinct()
                .map(ArrayList::new)
                .collect(Collectors.toList());
    }
}

【讨论】:

  • 请注意,您需要从 java.util 导入 ArraysObjects,并从 java.util.stream 导入 CollectorsStream 的 javadoc 更详细地介绍了 distinctmapcollect 方法,但 distinct 消除了重复项,map 将每个元素转换为不同的类型,collect 将列表的元素。
  • a = list.get(0); b = list.get(1); 的代码行是什么?你能解释一下他们应该做什么,我的意思是硬编码的索引看起来很奇怪。
  • @nullpointer 它只是用列表中的两个值初始化Pair - 它可能会受益于列表上的一些验证(即确保输入包含两个且仅两个值),但我试图避免一些混乱。每个内部列表都应该是两个值,因此基本上将 List 转换为 Pair
  • 每个内部列表都应该是两个值,因此基本上将列表转换为对 ..值得一提的假设恕我直言。
  • 建议的流解决方案加一个 :)
【解决方案2】:

另一种解决方案是对列表进行排序,然后通过distinct 运行它们,虽然这不是很有效,而且您还会获得一组排序列表:

Set<List<Integer>> collect = set.stream()
            .map(list -> {
                list.sort(Comparator.comparingInt(Integer::intValue));
                return list;
            })
            .distinct()
            .collect(Collectors.toSet());

【讨论】:

  • Integer 对象的int 值排序是自然顺序,因此,您可以使用list.sort(Comparator.naturalOrder()) 甚至只使用list.sort(null)。而当你收集到Set时,就不需要前面的distinct()了。
【解决方案3】:

您还需要将内部列表转换为集合。

【讨论】:

  • 是的,我试过了,但问题是我将采用另一种解决方案。因为如果我使用它,我应该检查我项目中的很多东西
  • 我的意思是,您需要将内部列表转换为集合,然后再次转换回列表,就像您对已经包含它们的列表所做的那样。
  • 好的。但是如何返回一个 ArrayList> 代替 Set>.
猜你喜欢
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
  • 2018-05-29
  • 1970-01-01
  • 2016-03-16
  • 2014-03-25
  • 2015-12-12
  • 1970-01-01
相关资源
最近更新 更多