java - 从数组列表中删除元素的最有效方法?

标签 java performance oop arraylist

<分区>

我正在研究 OOP,并且遇到了数组列表。我想知道 remove() 函数的实际工作原理,以及最有效的使用方法。


第一种删除所有“BB”的方法

public class ArrayListTest {
    public static void main(String args[]){
        ArrayList<String> Alist = new ArrayList<String>();
        Alist.add("AA");
        Alist.add("BB");
        Alist.add("AA");
        Alist.add("AA");
        Alist.add("AA");
        Alist.add("BB");
        System.out.println("Original ArrayList : " + Alist);
        int n = 0 ;
        for (int i = 0; i < Alist.size(); i++){
            n++;
            Alist.remove("BB");
        }
        System.out.println(n);
        System.out.println("Modified ArrayList : " + Alist);
    }
}

输出

run:
Original ArrayList : [AA, BB, AA, AA, AA, BB]
4
Modified ArrayList : [AA, AA, AA, AA]
BUILD SUCCESSFUL (total time: 0 seconds)

第二种删除所有“BB”的方法

public class ArrayListTest {
    public static void main(String args[]){
        ArrayList<String> Alist = new ArrayList<String>();
        Alist.add("AA");
        Alist.add("BB");
        Alist.add("AA");
        Alist.add("AA");
        Alist.add("AA");
        Alist.add("BB");
        System.out.println("Original ArrayList : " + Alist);
        int n = 0 ;
        while(Alist.contains("BB")){
            n++;
            Alist.remove("BB");
        }

        System.out.println(n);
        System.out.println("Modified ArrayList : " + Alist);
    }
}

输出

run:
Original ArrayList : [AA, BB, AA, AA, AA, BB]
2
Modified ArrayList : [AA, AA, AA, AA]
BUILD SUCCESSFUL (total time: 0 seconds)

这很令人困惑,因为计数器在第一个中被触发增加了几次,但它实际上更有效,还是“contains()”在每次检查后面的语句时循环遍历整个数组列表场景。

最佳答案

从数组列表中删除的最有效方法可能是:

Alist.removeAll(Collections.singleton("BB"))

Alist.removeIf("BB"::equals)

这些方法比单独调用 remove 更有效,因为实际的删除可以推迟到所有等于 "BB" 的元素都被识别出来。

这很重要,因为从 ArrayList 中删除一个元素会将所有具有较大索引的元素“向下移动一个”。在最坏的情况下(当所有列表元素都等于您要删除的东西时),单个列表删除调用将是列表元素数量的二次方; removeAllremoveIf 将是线性的,因为它们可以只移动一次未删除的元素,而根本不会移动要删除的元素。


第一种方法中最明显的低效是,您调用 remove 的次数与列表元素的数量一样多,而不管该项目在列表中出现了多少次。在一个特别病态的例子中,您可能在列表中有 1M 个元素,其中没有一个元素等于 "BB":您仍然会调用 remove 1M 次。

第二种方法中最明显的低效是您先调用contains,然后再调用remove。通过这样做,您正在查找该元素两次。

一个更有效的方法 - 但仍然比这个答案开头的两种方法效率低 - 将使用 the return value of remove ,这是一个 boolean 值,指示元素是否实际被删除。一旦 remove 返回 false,就没有必要再次调用 remove,因为找不到该元素:

while (Alist.remove("BB")) {}

关于java - 从数组列表中删除元素的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55933497/

相关文章:

javascript - 如何在 javascript 的类中用对象包装函数?

java - 在 Java 中编写 boolean 表达式的首选方法是什么

java - 无法在 Spring Boot 上构建可执行 JAR

java - Eclipse 中 Java 的定制内容辅助

java - 性能:Apache HttpAsyncClient与多线程URLConnection

php - MVC 模式——正确的思考方式

java - 如何在 Spring 3.x 中使用 Hibernate @Valid 约束?

java - 改进搜索功能

MySQL查询以获得特定排名

java - 实现java对象之间通信的正确方法是什么?