`
这些年
  • 浏览: 400379 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

zy19982004--容器学习七:ArrayList源码分析

 
阅读更多

一.成员变量

Java代码  收藏代码
  1. // 在AbstractList里面定义的  
  2. protected transient int modCount = 0;  
  3.   
  4. // 内部用数组实现  
  5. private transient Object[] elementData;  
  6.   
  7. private int size;  

 

二.构造函数

Java代码  收藏代码
  1. // 自己在写代码的时候为了严谨,最好是先判断参数抛出IllegalArgumentException  
  2. public ArrayList(int initialCapacity) {  
  3.     super();  
  4.     if (initialCapacity < 0)  
  5.         throw new IllegalArgumentException("Illegal Capacity: "  
  6.                 + initialCapacity);  
  7.     this.elementData = new Object[initialCapacity];  
  8. }  
  9.   
  10. // 初始化容量10  
  11. public ArrayList() {  
  12.     this(10);  
  13. }  

 

 三.存数据

Java代码  收藏代码
  1. //增加数据  
  2. public boolean add(E e) {  
  3.     //1.保证容量,size+1和容量比较,看是否有位置插入e  
  4.     ensureCapacity(size + 1); // Increments modCount!!  
  5.     //2.直接赋值  
  6.     elementData[size++] = e;  
  7.     return true;  
  8. }  
  9.   
  10. //在指定位置增加数据  
  11. public void add(int index, E element) {  
  12.     if (index > size || index < 0)  
  13.         throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  14.                 + size);  
  15.     //1.保证容量  
  16.     ensureCapacity(size + 1); // Increments modCount!!  
  17.     //2.向右移动当前位于该位置的元素(如果有)以及所有后续元素(将其索引加 1)。   
  18.     System.arraycopy(elementData, index, elementData, index + 1, size  
  19.             - index);  
  20.     //3.将指定的元素插入此列表中的指定位置  
  21.     elementData[index] = element;  
  22.     size++;  
  23. }  
  24.   
  25. // 检查容量,minCapacity=size+1  
  26. public void ensureCapacity(int minCapacity) {  
  27.     modCount++;  
  28.     int oldCapacity = elementData.length;  
  29.     // 如果超过容量  
  30.     if (minCapacity > oldCapacity) {  
  31.         Object oldData[] = elementData;  
  32.         // 新容量=(老容量 * 3)/2 + 1  
  33.         // 如果老容量为10,则新容量为16  
  34.         int newCapacity = (oldCapacity * 3) / 2 + 1;  
  35.         //newCapacity < minCapacity会产生这样的情况?????  
  36.         if (newCapacity < minCapacity)  
  37.             newCapacity = minCapacity;  
  38.         //复制原数组数据到大小为newCapacity的数组中  
  39.         elementData = Arrays.copyOf(elementData, newCapacity);  
  40.     }  
  41. }  
  42.   
  43. //替换数据  
  44. public E set(int index, E element) {  
  45.     RangeCheck(index);  
  46.     //保存index处旧值  
  47.     E oldValue = (E) elementData[index];  
  48.     //赋新值  
  49.     elementData[index] = element;  
  50.     return oldValue;  
  51. }  
  52. //下标志检查  
  53. private void RangeCheck(int index) {  
  54.     if (index >= size)  
  55.         throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  56.                 + size);  
  57. }  

 

四.取数据

Java代码  收藏代码
  1. public E get(int index) {  
  2.     RangeCheck(index);  
  3.     return (E) elementData[index];  
  4. }  
  5.   
  6. // 返回第一次出现o的下标,用equals比较  
  7. // 如果不存在o,返回-1  
  8. public int indexOf(Object o) {  
  9.     if (o == null) {  
  10.         for (int i = 0; i < size; i++)  
  11.             if (elementData[i] == null)  
  12.                 return i;  
  13.     } else {  
  14.         for (int i = 0; i < size; i++)  
  15.             if (o.equals(elementData[i]))  
  16.                 return i;  
  17.     }  
  18.     return -1;  
  19. }  
  20.   
  21. // 想想为什么不这么实现  
  22. // 上面的实现方式比较次数2+n,下面的比较次数2*n  
  23. public int indexOf(Object o) {  
  24.     for (int i = 0; i < size; i++) {  
  25.         if (o == null) {  
  26.             if (elementData[i] == null)  
  27.                 return i;  
  28.         } else {  
  29.             if (o.equals(elementData[i]))  
  30.                 return i;  
  31.         }  
  32.     }  
  33.     return -1;  
  34. }  
  35.   
  36. // 从size-1往0遍历  
  37. public int lastIndexOf(Object o) {  
  38.     if (o == null) {  
  39.         for (int i = size - 1; i >= 0; i--)  
  40.             if (elementData[i] == null)  
  41.                 return i;  
  42.     } else {  
  43.         for (int i = size - 1; i >= 0; i--)  
  44.             if (o.equals(elementData[i]))  
  45.                 return i;  
  46.     }  
  47.     return -1;  
  48. }  

 

五.删数据

Java代码  收藏代码
  1. //移除index处的元素是List接口里新加的方法  
  2. //同Map一样,在插入元素的操作中会扩容,删除元素并不去减容  
  3. public E remove(int index) {  
  4.     RangeCheck(index);  
  5.   
  6.     modCount++;  
  7.     E oldValue = (E) elementData[index];  
  8.     //需要移动的元素个数  
  9.     int numMoved = size - index - 1;  
  10.     if (numMoved > 0)  
  11.         //数组内(间)元素移动,五个参数依次为  
  12.         //src - 源数组。  
  13.         //srcPos - 源数组中的起始位置。  
  14.         //dest - 目标数组。  
  15.         //destPos - 目标数据中的起始位置。  
  16.         //length - 要复制的数组元素的数量。  
  17.         System.arraycopy(elementData, index + 1, elementData, index,  
  18.                 numMoved);  
  19.     //让GC回收因移动空出的数组最后一位  
  20.     elementData[--size] = null;   
  21.   
  22.     return oldValue;  
  23. }  
  24.   
  25. //remove某个元素是Collection接口里的方法  
  26. //同Map一样,在插入元素的操作中会扩容,删除元素并不去减容  
  27. //remove(int index)和remove(Object o)一次只会移除一个元素  
  28. public boolean remove(Object o) {  
  29.     if (o == null) {  
  30.         for (int index = 0; index < size; index++)  
  31.             if (elementData[index] == null) {  
  32.                 fastRemove(index);  
  33.                 return true;  
  34.             }  
  35.     } else {  
  36.         for (int index = 0; index < size; index++)  
  37.             if (o.equals(elementData[index])) {  
  38.                 fastRemove(index);  
  39.                 return true;  
  40.             }  
  41.     }  
  42.     return false;  
  43. }  
  44.   
  45. //把index后的元素移往前移一位  
  46. private void fastRemove(int index) {  
  47.     modCount++;  
  48.     int numMoved = size - index - 1;  
  49.     if (numMoved > 0)  
  50.         System.arraycopy(elementData, index + 1, elementData, index,  
  51.                 numMoved);  
  52.     //让GC回收因移动空出的数组最后一位  
  53.     elementData[--size] = null;   
  54. }  

 

六.List与Array

Java代码  收藏代码
  1. //ArrayList转换成数组  
  2. //将ArrayList内部的数组0到size-1位返回即可  
  3. public Object[] toArray() {  
  4.     return Arrays.copyOf(elementData, size);  
  5. }  
  6.   
  7. //ArrayList转换成指定数组a  
  8. public <T> T[] toArray(T[] a) {  
  9.     if (a.length < size)  
  10.         // Make a new array of a's runtime type, but my contents:  
  11.         return (T[]) Arrays.copyOf(elementData, size, a.getClass());  
  12.     System.arraycopy(elementData, 0, a, 0, size);  
  13.     if (a.length > size)  
  14.         a[size] = null;  
  15.     return a;  
  16. }  

 

分享到:
评论

相关推荐

    02-Java集合容器面试题(2020最新版)-重点.pdf

    ### Java集合容器知识点详解 #### 一、集合容器概述 - **定义**:集合容器是Java平台提供的标准组件,主要用于存储对象。...通过本篇文章的学习,希望读者能够更好地理解和应用Java集合容器,提升编程技能。

    jdk源码阅读一:ArrayList

    通过深入分析ArrayList的源码,我们可以更好地理解其工作原理以及优化策略。这些知识点对于开发高效稳定的Java程序至关重要。对于需要频繁访问和修改的数据集,使用ArrayList可以带来性能上的显著提升。然而,在多...

    深入Java集合学习系列:ArrayList的实现原理

    《深入Java集合学习系列:ArrayList的实现原理》 在Java编程中,ArrayList是集合框架中一个重要的类,属于List接口的实现,它提供了动态数组的功能,允许我们在集合中存储、添加、删除元素,并且可以按索引访问。这...

    Java试题-2:ArrayList类动态代理

    Java试题-2:ArrayList类动态代理 什么是动态代理 动态代理该怎么实现

    java 复习题

    **选项分析:** - **A**:`public abstract method();` 此项缺少方法名。 - **B**:`public abstract void method();` 抽象方法不需要方法体,此选项正确。 - **C**:`public abstract void method() {};` 抽象方法...

    Java基础-ArrayList方法全解(上).pdf

    ArrayList是Java集合框架中常用的动态数组,它允许我们在运行时添加、删除和访问元素。在Java中,ArrayList实现了List接口,因此它支持有序...记住,学习ArrayList不仅是掌握方法,更是理解其在不同场景下的最佳实践。

    Java容器类List、ArrayList、Vector及map、HashTable应用

    ### Java容器类详解:List、ArrayList、Vector及Map、HashTable应用 #### 一、Java容器类概述 在Java中,容器类(也称为集合类)主要用于存储和管理对象。Java SDK提供了一系列内置容器类,它们位于`java.util`...

    Java 最常见的 208 道面试题:第二模块答案

    【Java 容器详解】 Java 容器是 Java 核心库的重要组成部分,它们提供了存储和管理对象的方式。常见的容器包括以下几类: 1. **集合接口**:主要有 Collection 和 Map 两大接口。 - **Collection**:代表一组不...

    thinkinjava源码-Thinking-in-java:Java编程思想源码及习题!

    - **集合框架**:Java的ArrayList, LinkedList, HashMap等容器类的使用会在源码中体现,帮助理解数据存储和操作。 - **泛型**:源码将展示如何使用泛型编写类型安全的代码,减少类型转换的麻烦。 - **枚举**:...

    阿里校招社招常考面试题(86题 11页).pdf

    2. **Tomcat**:不仅可以解析 JSP 动态页面,还可以作为 Servlet 容器。 3. **JBoss**:是一个全面的应用服务器,可以部署各种 Java 应用。 #### 五、GET 与 POST 区别 1. **数据提交方式**: - **GET**:通过 ...

    java ArrayList的使用与分析

    【Java ArrayList 使用与分析】 ArrayList 是 Java 集合框架中的一个重要组成部分,它是一个基于数组实现的可变大小的列表。ArrayList 类继承自 AbstractList 类并实现了 List 接口,这意味着它可以被用作一个有序...

    java入门 练习题题库

    #### 七、super关键字的使用 - **知识点**: `super`关键字用于调用父类的方法或属性,在构造方法中调用父类的构造方法。 - **解析**: - `super(C)`表示在子类构造方法中调用父类构造方法,并传递参数C。 - 选项...

    2024年java面试题-java集合相关面试题

    ### 一、集合容器概述 #### 1. 什么是集合? 集合(Collection)是指在Java中用来存储、检索及操作一组对象的一种容器。它是一种高级的数据结构,主要用于管理一组对象,而不仅仅是简单地存储这些对象。 #### 2. ...

    Java试题及标准答案abc.doc

    题目询问如何正确地构造一个实现了`List`接口的`ArrayList`实例。正确的选项是**B**:`List myList=new ArrayList〔〕;` - **A**:`ArrayList myList=new Object〔〕;` 这个选项错误是因为它创建了一个`Object`...

    java提高篇(二一)-----ArrayList.pdf

    ArrayList 源码分析: ArrayList 底层采用数组实现,所以它的操作基本上都是基于对数组的操作。ArrayList 提供了三个构造函数: 1. ArrayList():默认构造函数,提供初始容量为 10 的空列表。 2. ArrayList(int ...

    java面试题

    #### 七、ArrayList、Vector、LinkedList的存储性能和特性 - **ArrayList**:基于动态数组实现,适合随机访问。 - **Vector**:与 ArrayList 类似,但所有操作都是线程安全的,性能相对较低。 - **LinkedList**:...

    Java 基础 常识

    #### 七、ArrayList、Vector、LinkedList的存储性能和特性 - **ArrayList**: - **特性**:基于数组实现,支持随机访问。 - **性能**:插入和删除效率低。 - **Vector**: - **特性**:与`ArrayList`类似,但...

    java 学习笔记

    在Java学习笔记中,我们重点关注Java的IO(输入/输出)操作、常用类库以及集合框架。 1. **Java IO**: - **File类**:提供了文件和目录的基本操作,如创建、删除、重命名等。 - **RandomAccessFile**:支持对...

    java.util源码-java-source-code:java.util源码阅读

    Java.util 源码分析 Java.util 包是 Java 核心库的重要组成部分,它包含了许多用于日常编程的工具类和接口,如集合框架、日期时间处理、随机数生成、事件处理等。深入理解这个包的源码对于提升Java开发者的技能至关...

Global site tag (gtag.js) - Google Analytics