如何从 ArrayList 中删除重复项?(Java)

huangapple go评论82阅读模式
英文:

How would I remove duplicates from an Arraylist<Integer[]>? (Java)

问题

问题已经说得很清楚了。我尝试过使用LinkedHashSet,但没有起作用。如果我没错的话,比较是不正确的,因为它在比较整数数组。

我的目标是创建一个静态方法removeDuplicates(ArrayList<Integer>)。该方法应该基于数组的内容进行比较。我目前的尝试:

import java.util.ArrayList;
import java.util.LinkedHashSet;

public class test {
    public static void main(String[] args) {
        ArrayList&lt;Integer[]&gt; arrayList = new ArrayList&lt;&gt;();

        Integer[] array1 = new Integer[2];
        array1[0] = 1;
        array1[1] = 4;

        Integer[] array2 = new Integer[2];
        array2[0] = 1;
        array2[1] = 4;

        arrayList.add(array1);
        arrayList.add(array2);

        LinkedHashSet&lt;Integer[]&gt; hashSet = new LinkedHashSet&lt;&gt;(arrayList);

        ArrayList&lt;Integer[]&gt; listWithoutDuplicates = new ArrayList&lt;&gt;(hashSet);

        System.out.println(&quot;使用LinkedHashSet之前的元素数量&quot; + arrayList.size());
        System.out.println(&quot;使用LinkedHashSet之后的元素数量期望为1):&quot; + listWithoutDuplicates.size());
    }
}

得到的结果:

使用LinkedHashSet之前的元素数量:2
使用LinkedHashSet之后的元素数量(期望为1):2
英文:

Question says it all really. I tried using a LinkedHashSet but that did not work. If im not wrong, the comparisons were not being done correctly due to the fact that it was comparing Integer arrays.

My aim is to create a static method removeDuplicates(ArrayList&lt;Integer&gt;). The method should compare based on content of the arrays. My attempt so far:

import java.util.ArrayList;
import java.util.LinkedHashSet;

public class test {
    public static void main(String[] args) {
        ArrayList&lt;Integer[]&gt; arrayList = new ArrayList&lt;&gt;();

        Integer[] array1 = new Integer[2];
        array1[0] = 1;
        array1[1] = 4;

        Integer[] array2 = new Integer[2];
        array2[0] = 1;
        array2[1] = 4;

        arrayList.add(array1);
        arrayList.add(array2);

        LinkedHashSet&lt;Integer[]&gt; hashSet = new LinkedHashSet&lt;&gt;(arrayList);

        ArrayList&lt;Integer[]&gt; listWithoutDuplicates = new ArrayList&lt;&gt;(hashSet);

        System.out.println(&quot;Number of elements before using linkedhashset: &quot; + arrayList.size());
        System.out.println(&quot;number of elements after: (expecting 1) &quot; + listWithoutDuplicates.size());
    }
}

gives the result:

Number of elements before using linkedhashset: 2
number of elements after (expecting 1):  2

答案1

得分: 3

可能的解决方案是保存列表中每个数组中每个数字的出现次数,以考虑重复数字,并检查是否已添加此实例:

private static List<Integer[]> removeDuplicates(List<Integer[]> list) {
    List<HashMap<Integer, Integer>> instances = new ArrayList<>();
    List<Integer[]> res = new ArrayList<>();
    for (Integer[] arr : list) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (Integer num : arr) {
            if (map.containsKey(num))
                map.replace(num, map.get(num) + 1);
            else
                map.put(num, 1);
        }
        if (!instances.contains(map)) {
            instances.add(map);
            res.add(arr);
        }
    }
    return res;
}
英文:

A possible solution would be saving the number of occurrences of each number in each array in the list to consider duplicate numbers, and check whether this instance was already added or not:

private static List&lt;Integer[]&gt; removeDuplicates(List&lt;Integer[]&gt; list) {
		List&lt;HashMap&lt;Integer,Integer&gt;&gt; instances = new ArrayList&lt;&gt;();
		List&lt;Integer[]&gt; res = new ArrayList&lt;&gt;();
		for(Integer[] arr : list) {
			HashMap&lt;Integer,Integer&gt; map = new HashMap&lt;&gt;();
			for(Integer num : arr) {
				if(map.containsKey(num))
					map.replace(num, map.get(num)+1);
				else
					map.put(num,1);
			}
			if(!instances.contains(map)) {
				instances.add(map);
				res.add(arr);
			}
		}
		return res;
}

答案2

得分: 3

以下是翻译好的部分:

可以使用以下方法:

List<Integer[]> listWithoutDuplicates = arrayList.stream()
                .map(arr -> Arrays.asList(arr))
                .distinct()
                .map(list -> list.toArray(new Integer[0]))
                .collect(Collectors.toList());

这里的诀窍是将 Integer[] 映射为 List<Integer>,这允许您使用 List::equals() 方法来检测两个列表是否相等(即“两个列表包含相同元素且顺序相同”)。结合 Stream::distinct(),它将删除重复项,然后每个唯一的 List 被转换回 Integer[]

英文:

You can use following approach

List&lt;Integer[]&gt; listWithoutDuplicates = arrayList.stream()
            .map(arr -&gt; Arrays.asList(arr))
            .distinct()
            .map(list -&gt; list.toArray(new Integer[0]))
            .collect(Collectors.toList());

The trick here is that mapping Integer[] to List&lt;Integer&gt; allows you to utilize List::equals() method that can detect if two Lists are equal (= "both contain same elements in same order"). In conjunction with Stream::distinct() that will cut off duplicates, and then every unique List is converted back to Integer[].

huangapple
  • 本文由 发表于 2020年4月9日 01:02:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/61106067.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定