美文网首页
自定义ArrayList,删除元素时的注意点

自定义ArrayList,删除元素时的注意点

作者: junjun2018 | 来源:发表于2018-07-31 13:59 被阅读0次

自己实现一个ArrayList,添加2,4,5,6,6,7元素之后再删除元素中的偶数元素。

public class MyArrayList {
    private static final int Default_Capacity = 3;
    private Object[] objs = new Object[Default_Capacity];
    private int size = 0;

    public int getSize() {
        return size;
    }

    //添加元素
    public void add(Object element) {
        //索引等于长度,扩容
        if (size == objs.length) {
            //扩容两倍
            Object[] temp = new Object[size * 2];
            //数据搬家
            for (int i = 0; i < objs.length; i++) {
                temp[i] = objs[i];
            }
            //更改指向
            objs = temp;

        }
        //在末尾添加元素
        objs[size] = element;
        size++;
    }

    //删除指定索引处的元素
    public void removeElement(int index) {
        if (index >= size) {
            throw new ArrayIndexOutOfBoundsException("索引越界");
        }
        //将后面的元素向前移动一位
        for (int i = index + 1; i < size; i++) {
            objs[i - 1] = objs[i];
        }
        size--;
    }

    //获取索引处的元素
    public Object get(int index) {
        if (index >= size) {
            throw new ArrayIndexOutOfBoundsException("索引越界");
        }
        return objs[index];
    }

    @Test
    public void testArrayList() {
        MyArrayList list = new MyArrayList();
        list.add(2);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(6);
        list.add(7);
        //结果对吗?正向遍历的时候,移除元素,会造成列表中后面的元素向前移动,此时索引将不会对应原来的数据。
//        for (int i = 0; i < list.getSize(); i++) {
//            if ((int) list.get(i) % 2 == 0) {
//                list.removeElement(i);
//            }
//        }
        //反向遍历可以解决问题。因为从后面移除的元素,将不会影响到前面元素的顺序
        for (int i = list.getSize() - 1; i >= 0; i--) {
            if ((int) list.get(i) % 2 == 0) {
                list.removeElement(i);
            }
        }
        printList(list);
    }

    private void printList(MyArrayList list) {
        for (int i = 0; i < list.getSize(); i++) {
            System.out.println(list.get(i));
        }
    }
}
//正向遍历结果:
4
5
6
7
//反向遍历结果
5
7

总结:假设此list中已经扩容到100万,当在添加一个的时候,容量就会再次扩大,并且会将100万条数据赋值到新的列表,效率会很低。
删除操作中,会伴随着后面元素的前移,删除的元素越在前,效率越低。所以,基于数组实现的ArrayList做不适合做大数据量的增删操作!
而查询则是根据数组的索引进行查询,效率会很高。

而基于双向链表实现的LinkedList,增加元素,则可以从head直接跳到尾部,然后执行添加元素,而不用管列表中已经存在10万,还是100万数据,所以添加效率相当高。
删除元素,元素越是处在中间则效率越低,同样是删除第一个元素,ArrayList会将数组后面所有的元素往前移动,而LinkList则是直接找到head元素,将其next的元素引用指向最后一个元素形成闭环即可,效率明显比ArrayList高太多。至于删除最后一个元素,ArrayList效率很高,因为不会产生元素前移,LinkList由于是双链表结构,也可以很快速的从头直接跳到尾部删除最后的元素。

遍历数据:基于数组实现的ArrayList在遍历时,效率会相当高。而LinkedList则查找每一个元素都要从头开始去找。效率非常低下。

综上:ArrayList增删慢,查询快。LinkedList增删快,查询慢。实际使用中,一般动态数据变化,增删操作频繁时,首选LinkedList。如果多做的是些查询操作,则选用ArrayList。

相关文章

网友评论

      本文标题:自定义ArrayList,删除元素时的注意点

      本文链接:https://www.haomeiwen.com/subject/pbthvftx.html