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

Ram*_*ami 1 java oop performance 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 Code Online (Sandbox Code Playgroud)

输出

run:
Original ArrayList : [AA, BB, AA, AA, AA, BB]
4
Modified ArrayList : [AA, AA, AA, AA]
BUILD SUCCESSFUL (total time: 0 seconds)
Run Code Online (Sandbox Code Playgroud)

删除所有“ 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 Code Online (Sandbox Code Playgroud)

输出

run:
Original ArrayList : [AA, BB, AA, AA, AA, BB]
2
Modified ArrayList : [AA, AA, AA, AA]
BUILD SUCCESSFUL (total time: 0 seconds)
Run Code Online (Sandbox Code Playgroud)

这很令人困惑,因为在第一个计数器中触发了该计数器再增加几次,但实际上效率更高,还是在幕后语句的每次检查中“ contains()”遍历整个数组列表。

And*_*ner 8

从arraylist中删除的最有效方法可能是:

Alist.removeAll(Collections.singleton("BB"))
Run Code Online (Sandbox Code Playgroud)

要么

Alist.removeIf("BB"::equals)
Run Code Online (Sandbox Code Playgroud)

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

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


第一种方法最明显的效率低下是remove,无论项目在列表中出现多少次,您都调用了与列表元素一样多的次数。在一个特别的病理示例中,列表中可能有1M个元素,但它们都不等于"BB":您仍要调用remove1M次。

第二种方法中最明显的低效率是先调用contains然后再调用remove。通过执行此操作,您正在查找元素两次。

一种更有效的方法-但仍比该答案开头的两种方法效率低-将使用的返回值remove,这是一个布尔值,指示是否实际删除了元素。一旦removereturn false,remove再次调用就没有意义,因为找不到该元素:

while (Alist.remove("BB")) {}
Run Code Online (Sandbox Code Playgroud)


YCF*_*F_L 7

如果您使用的是Java8,则只需要:

aList.removeIf(s -> s.equals("BB"));
Run Code Online (Sandbox Code Playgroud)

或简称:

aList.removeIf("B"::equals);
Run Code Online (Sandbox Code Playgroud)

如果您注意的话,这种方式不需要检查列表中元素是否存在。


作为一个好的做法:

  • 不要在首字母大写的地方命名变量Alist,而要使用aList例如