首页 文章

从ArrayList中删除重复项?

提问于
浏览
-2

大家下午好,我正在学习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);
        }
    }
}

}

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

6 回答

  • 0

    list.contains(list.get(i)) 始终返回 true ,因为 Listi '元素包含在 List 中 .

    因此 removeDuplicate 正在尝试删除所有元素(但是你只删除了其中的一半,因为在删除 i '元素之后你跳过了新的 i 元素) .

    有很多方法可以删除重复项 . 最有效的涉及使用 HashSet . 如果要仅使用 List 方法查找重复项,可以检查是否 list.lastIndexOf(list.get(i)) > i .

  • 0

    您正在获取list.get(i)当然存在于列表中,您将删除最后的所有值 . 您可以使用集合删除它们:

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

    如果您想保留当前订单而不想使用set .

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

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

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

    如果您可以自由选择集合,则应使用 LinkedHashSet 代替 . 它包含有序的唯一数字 .

  • 0

    表达式 list.contains(list.get(i)) 始终为true,因为您询问列表是否包含列表中的某些元素 . 您需要检查 list.get(i) 是否包含在列表中的第一个 i-1 项中,我建议您使用循环 .

    请注意,带有 list.remove 的循环将运行缓慢,因为从 ArrayList 删除项目i是通过将项目i替换为i 1,然后将项目i 1替换为i 2,依此类推 . 这意味着需要大约 length^2 时间来创建一个在每次迭代中调用remove的循环 . 函数 list.contains 具有相同的问题,因为它必须遍历整个列表 . 如果您有10个项目,这可能无关紧要,但如果您有一个包含一百万个项目的列表,则需要很长时间才能运行 .

  • 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--;
        }
    }
    

相关问题