Android开发数据结构算法ArrayList源码详解

Android开发数据结构算法ArrayList源码详解

概述

Android开发中,大量使用到了数据结构和算法,ArrayList便是其中的一种非常重要的数据结构。ArrayList是Java中非常重要且使用率非常高的一种数据结构,Android开发中也经常使用它来存储数据。本文将深入探究ArrayList的源码,帮助读者更好地理解其工作原理和使用方法。

ArrayList介绍

在Java中,ArrayList是List接口的动态数组实现。其中,动态数组是指可以动态添加或删除元素的数组。ArrayList底层采用数组实现,因此查询效率非常高,随机访问元素的效率也很高。但是,当添加或删除元素时,可能需要移动其他元素,因此效率稍低。

ArrayList的一个重要特性是允许包含重复元素,也允许包含null元素。使用时需要引入java.util包。

ArrayList源码详解

ArrayList源码浏览需要从以下方面进行考虑:

  1. ArrayList属性;
  2. ArrayList构造函数;
  3. ArrayList普通方法;
  4. ArrayList迭代器方法;
  5. ArrayList实现List接口方法。

ArrayList属性

ArrayList的属性主要有以下几个:

// 底层使用的数组
private transient Object[] elementData;

// 当前ArrayList元素个数
private int size;

// ArrayList初始容量,默认为10
private static final int DEFAULT_CAPACITY = 10;

// 空数组缓存
private static final Object[] EMPTY_ELEMENTDATA = {};

// 空数组缓存,用于默认大小的空实例
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

ArrayList构造函数

ArrayList提供了多种构造函数:

// 创建一个空ArrayList对象
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

// 创建一个包含指定数量的元素列表的ArrayList对象
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
    }
}

// 创建一个包含指定集合中元素的ArrayList对象,并按照集合迭代器的顺序返回元素
public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

ArrayList普通方法

ArrayList的普通方法包含了添加、删除、查找和遍历等常用操作,以下是其中几个重要方法的源码解析:

add方法

// 将指定的元素添加到ArrayList的末尾
public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}

// 在指定位置插入指定元素,需要移动其后元素
public void add(int index, E element) {
    rangeCheckForAdd(index);

    modCount++;
    ensureCapacityInternal(size + 1);
    System.arraycopy(elementData, index, elementData, index + 1, size - index);
    elementData[index] = element;
    size++;
}

// 确保ArrayList的容量足够,使用拷贝的方式进行容量扩充
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

// 根据需要扩充ArrayList的容量
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // 如果指定的容量大于数组容量,则需要扩容
    if (minCapacity - elementData.length > 0) {
        grow(minCapacity);
    }
}

//  对数组进行扩容,并将原数组中的元素拷贝到新数组中
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

remove方法

// 移除指定位置的元素
public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    // clear to let GC do its work
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

// 移除指定元素
public boolean remove(Object o) {
    if (o == null) {
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                fastRemove(index);
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

// 快速移除指定位置的元素
private void fastRemove(int index) {
    modCount++;
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work
}

get方法

// 返回指定位置的元素
public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

ArrayList迭代器方法

ArrayList提供了两种迭代器:

// 返回一个ListIterator对象,可以遍历ArrayList集合中的元素
public ListIterator<E> listIterator(int index) {
    if (index < 0 || index > size)
        throw new IndexOutOfBoundsException("Index: "+index);

    return new ListItr(index);
}

// 返回一个迭代器,可以遍历ArrayList集合中的元素
public Iterator<E> iterator() {
    return new Itr();
}

ArrayList实现List接口方法

ArrayList实现了List接口中的所有方法,以下是其中一些方法的源码解析:

// 添加指定集合中的所有元素
public boolean addAll(Collection<? extends E> c) {
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // 扩容
    System.arraycopy(a, 0, elementData, size, numNew);
    size += numNew;
    return numNew != 0;
}

// 移除ArrayList中的所有元素
public void clear() {
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

// 判断ArrayList是否包含指定元素
public boolean contains(Object o) {
    return indexOf(o) >= 0;
}

// 返回ArrayList中指定元素的第一个索引,如果不存在则返回-1
public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

// 将指定元素插入到ArrayList中的指定位置
public void add(int index, E element) {
    rangeCheckForAdd(index);

    modCount++;
    ensureCapacityInternal(size + 1); // 扩容
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

示例说明

以下两个示例演示了ArrayList的基本用法:

示例一:使用ArrayList存储并遍历学生信息

// 定义学生类
class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

// 存储并遍历学生信息
ArrayList<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 18));
studentList.add(new Student("李四", 20));
studentList.add(new Student("王五", 22));

for (Student s : studentList) {
    System.out.println("姓名:" + s.getName() + ",年龄:" + s.getAge());
}

示例二:对集合进行排序

// 定义一个整型ArrayList
ArrayList<Integer> list = new ArrayList<>();

// 向ArrayList中添加元素
list.add(10);
list.add(3);
list.add(5);
list.add(2);
list.add(7);

// 对ArrayList排序
Collections.sort(list);

// 打印排序后的ArrayList
System.out.println(list);

总结

本文详细介绍了Android开发中非常重要的数据结构之一——ArrayList。通过深入地学习ArrayList的源码实现和使用方法,读者可以更深入地理解ArrayList的工作原理和使用方法,从而更好地应用于实际开发中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android开发数据结构算法ArrayList源码详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 【ACM博弈论】SG函数入门(1):从巴什博奕到尼姆游戏

    在我小时候以前做题的时候,遇到博弈题往往都是漫无目的地打表找规律,或者找一些特殊情况但是没有很好的分析方法。 其实博弈题是有比较套路的解题方法的,那就是利用SG函数,第一节不会讲到SG函数的具体用法,我们先来博弈入个门,学习一下最基本的博弈类型:Nim游戏。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式…

    算法与数据结构 2023年4月17日
    00
  • 算法总结–ST表

    声明(叠甲):鄙人水平有限,本文为作者的学习总结,仅供参考。 1. RMQ 介绍 在开始介绍 ST 表前,我们先了解以下它以用的场景 RMQ问题 。RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ…

    算法与数据结构 2023年4月18日
    00
  • JavaScript树形数据结构处理

    对于“JavaScript树形数据结构处理”的完整攻略,我将从以下几个方面进行讲解: 树形数据结构的简介 树形数据结构在JavaScript中的表示 树形数据结构的处理方法 示例说明 树形数据结构的简介 树形数据结构,是一种常见的数据结构,由多个节点组成,每个节点有一个父节点和多个子节点。树形数据结构通常用来表示层级关系的数据。 树形数据结构在JavaScr…

    数据结构 2023年5月17日
    00
  • Java数据结构之基于比较的排序算法基本原理及具体实现

    Java数据结构之基于比较的排序算法基本原理及具体实现 前言 排序算法是计算机科学中最基本的算法之一,其广泛应用于各领域中。基于比较的排序算法是一种流行的排序算法类型,本篇文章将阐述其基本原理及具体实现,以帮助读者深入了解该算法。 算法介绍 基于比较的排序算法是根据元素之间的比较操作来完成排序的一种算法类型,它可以对各种数据类型进行排序,如整数、浮点数、字符…

    数据结构 2023年5月17日
    00
  • C语言 数据结构之数组模拟实现顺序表流程详解

    C语言 数据结构之数组模拟实现顺序表流程详解 什么是顺序表? 顺序表是一种基于连续存储结构的数据结构,它可以用一段连续的存储单元来存储线性表中的所有元素。 顺序表的实现思路 顺序表的实现主要依赖数组。我们可以定义一个数组来存储线性表的数据元素,同时再定义一个变量来保存线性表当前的长度。当需要对线性表进行插入、删除、查找等操作时,根据需求,可以通过数组的下标来…

    数据结构 2023年5月17日
    00
  • C语言全面讲解顺序表使用操作

    C语言全面讲解顺序表使用操作 什么是顺序表 顺序表(Sequential List)是一种常见的数据结构,它由一组连续的存储单元组成,并且支持随机访问。通常我们使用数组来实现顺序表。 顺序表的基本操作 初始化 在使用顺序表之前,需要先进行初始化。顺序表的初始化包括两个步骤:指定顺序表的大小,申请内存空间。具体代码如下: #define MAXSIZE 100…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构之链表的实现

    JavaScript数据结构之链表的实现 什么是链表 链表是一种线性数据结构,其中的元素在内存中不连续地存储,每个元素通常由一个存储元素本身的节点和一个指向下一个元素的引用组成。相比较于数组,链表具有如下优缺点: 优点:动态地添加或删除元素时,无需移动其它元素。(数组则需要移动其它元素) 缺点:不能随机地访问某个元素,必须从头开始顺序遍历。(而数组可以通过索…

    数据结构 2023年5月17日
    00
  • Java数据结构之双向链表图解

    以下是Java数据结构之双向链表图解的完整攻略: 一、双向链表简介 1.1 定义 双向链表(Doubly Linked List),也叫双向链式线性表,是链式存储结构的基本形式之一。双向链表的每个节点都含有两个指针,分别指向前驱节点和后继节点,因此可以支持双向遍历。 1.2 结构 双向链表的结构可以用下图表示: +——-+ +——-+ +–…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部