要从ArrayList中删除重复项吗?

时间:2018-12-09 19:03:39

标签: java

大家下午好,我目前正在学习Java Final,并且有一个复习练习,要求读者创建一个程序,该程序要求用户输入10个整数,然后使用一种方法来删除重复项并显示不同的清单。该方法也为您提供。 我已经编写了大部分代码,实际上我以为已经完成了,直到我意识到for循环要删除的不只是重复项。 这是我的代码:

public class lab25 {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);

    int i;

    //Create array list
    ArrayList<Integer> numbers = new ArrayList<>();

    System.out.println("Please enter 10 numbers!");

    //Populate
    for(i=0; i<10; i++) {
         numbers.add(input.nextInt());
    }

    System.out.println("Your numbers are: " + numbers.toString());
    removeDuplicate(numbers);
    System.out.println("The distinct numbers are: " +numbers.toString());  
    input.close();
}
public static void removeDuplicate(ArrayList<Integer> list) {
    int i;

    for(i=0; i<list.size(); i++) {
        if(list.contains(list.get(i))) {
            list.remove(i);
        }
    }
}

}

只是好奇我在这里做错了什么?我认为我的问题可能出在我的for循环中。.感谢所有回答。

6 个答案:

答案 0 :(得分:1)

list.contains(list.get(i))始终返回true,因为i的第List个元素包含在List中。

因此,removeDuplicate试图删除所有元素(但是您只删除了其中一半,因为在删除第i个元素之后,您跳过了第i个新元素)

有很多方法可以删除重复项。最有效的方法是使用HashSet。如果您只想使用List方法来查找重复项,则可以检查是否list.lastIndexOf(list.get(i)) > i

答案 1 :(得分:1)

表达式data-onlogin始终为true,因为您要询问列表是否包含列表中的某些元素。您需要检查列表的前_handleFBLogin = () => { FB.login(response => { this._facebookCallback(response) }, {scope: 'public_profile,email'}) } 个项目中是否包含list.contains(list.get(i)),建议您循环执行。

请注意,使用list.get(i)进行循环会很慢,因为从i-1删除项目i是通过将项目i替换为i + 1,然后将项目i + 1替换为i + 2来完成的。等等。这意味着大约需要list.remove时间来创建一个在每次迭代中都调用remove的循环。函数ArrayList存在相同的问题,因为它必须遍历整个列表。如果您有10个项目,这可能并不重要,但是如果您有一个包含一百万个项目的列表,则将需要很长时间才能运行。

答案 2 :(得分:0)

您正在获取list.get(i),它当然存在于列表中,最后您将删除所有值。 您可以使用以下设置将其删除:

Set<String> hs = new HashSet<>();
hs.addAll(numbers);
numbers.clear();
numbers.addAll(hs);

答案 3 :(得分:0)

如果您想保留当前订单并且不想使用set。

List<String> notduplicatedList =
    new ArrayList<>(new LinkedHashSet<>(String));

答案 4 :(得分:0)

最简单的方法是使用Stream.distinct()

public static List<Integer> removeDuplicate(List<Integer> list) {
    return list.stream().distinct().collect(Collectors.toList());
}

如果您可以自由选择收藏,则应改用LinkedHashSet。它保存有序的唯一编号。

答案 5 :(得分:0)

一个解决方案可能就是这个。我从列表的末尾开始,我不删除循环将来必须访问的索引。

public static void removeDuplicate(ArrayList<Integer> list) {
    int i = list.size() - 1;

    while (i > -1) {
        // check for duplicate
        for (int j = 0; j < i; j++) {
            if (list.get(i) == list.get(j)) {
                // is duplicate: remove
                list.remove(i);
                break;
            }
        }
        i--;
    }
}