1)题目:ArrayList的实现原理源码
2)思路:顺序表ArrayList,用数组表示,一组连续的地址空间。其实现的方法包括:
- 初始化线性表 ArrayList(int initialSize)
- 在线性表末尾添加元素add(E e)
- 更新update,将第index各数据替换掉 update(E e, int index)
- 删除指定位置的元素removeToIndex(int index)
- 根据下标返回元素值 get(int index)
- 判断表容量是否超出预定大小,如果超出将自动扩充容量ensureCapacity()
- 返回顺序表实际表长size()
- 返回表容量length()
- 判断表是否为空 isEmpty()
- 初始化指定大小的随机顺序表initRamdomList(int size)
- 初始化指定大小的非降序序顺序表initNotDecs(int size)
- 初始化指定大小的升序顺序表initacs(int size)
- 初始化指定大小的降序顺序表initDecs(int size)
- 返回顺序表的遍历数据toString()
3)代码实现:
package com.sam.datastruct.arrayList; import java.util.Arrays; import java.util.Date; import java.util.Random; /** * 顺序表ArrayList,用数组表示。一组连续的地址空间 * @author LH-PC * @param <E> */ public class ArrayList<E> { private Object[] data = null; //data 用来保存此线性表的数据域 private int length; //线性表的容量 private int current; //实际表长 /** * 默认将大小设置为10 */ public ArrayList(){ this(10); } /** * 初始化线性表,声明数组大小 * @param initialSize 数组大小 */ public ArrayList(int initialSize){ if(initialSize >= 0){ this.length = initialSize; //设置线性表容量 this.data = new Object[initialSize]; //初始化数组 this.current = 0; //下标设置为0 }else { throw new RuntimeException("初始化大小不能小于0:" + initialSize); //异常提示 } } /** * 在线性表末尾添加元素,添加之前判断线性表是否已经满了 * @param e 添加的元素 * @return 成功返回真 */ public boolean add(E e){ //判断是否已满 ensureCapacity(); //将元素添加到数组末尾 this.data[current++] = e; // ++current; //下标++ return true; } /** * 在线性表指定位置添加元素,添加之前判断线性表是否已经满了 * @param e 添加的元素 * @param index 指定位置的下标 * @return 成功返回真 */ public boolean add(E e, int index){ if (index < 0 || index > current) { //判断指定位置是否合法,不合法返回false System.err.print(new Date() + ": 下标不合法"); return false; } //判断是否已满 ensureCapacity(); //将index及后面的数据后移一位 for (int i = ++current; i > index; --i) { this.data[i] = data[i - 1]; } data[index] = e; return true; } //将第index各数据替换掉 public boolean update(E e, int index){ if (index < 0 || index >= current) { System.err.print(new Date() + ": 下标不合法"); } data[index] = e; return true; } public boolean remove(){ data[--current] = null; return true; } /** * 删除指定位置的元素 * @param index * @return */ public boolean removeToIndex(int index){ //删除数组的元素:使用改变数组下标的方式达到删除的效果。 //遍历数组匹配指定下标,让指定下标右边的元素往左移动改变下标。最后再将最右边的下标删除 //a b c //0 1 2 //data[index] = data[index + 1]; //改变右边下标 //data //删除最右边的下标 //从待删除下标处开始遍历,将右边的元素往左移 if(index < 0 || index >= current){ //如果index大于最大长度,返回false System.err.print(new Date() + ": 下标不合法"); return false; } for (int i = index; i < current - 1; i++) { data[i] = data[i+1]; //该表元素下标 } data[--current] = null; //将原来下标最右边的一位元素变成null // --current; //实际表长-1 return true; } /** * 根据下标返回元素值 * @param index * @return */ public E get(int index){ if(index >= 0){ return (E) data[index]; }else { throw new RuntimeException("下标不能小于0:" + index); } } /** * 判断表容量是否超出预定大小,如果超出将自动扩充容量 * */ public void ensureCapacity(){ //判断表实际长度是否超出表最大容量 if(current >= length){ length *= 2; //将表最大容量*2 data = Arrays.copyOf(data, length); //将原数组进行拷贝 } } /** * 返回顺序表实际表长 * @return */ public int size(){ return this.current; } /** * 返回表容量 * @return */ public int length(){ return this.length; } /** * * 判断表是否为空 * @param args */ public boolean isEmpty(){ //return (current == 0) ? true : false; return current == 0; //如果current == 0,说明为空返回真,否则返回假 } /** * 初始化指定大小的随机顺序表 * @param size */ public void initRamdomList(int size){ Random random = new Random(); StringBuffer sb = new StringBuffer(); for(current = 0; current < size; ++current){ ensureCapacity(); data[current] = random.nextInt(200); sb.append("," + data[current]); } System.out.println(sb.length() > 0 ? sb.substring(1) : ""); } /** * 初始化指定大小的非降序序顺序表 * @param size */ public void initNotDecs(int size){ ensureCapacity(); StringBuffer sb = new StringBuffer(); Random random = new Random(); data[0] = 1; System.out.print(data[0]); for(current = 1; current < size; ++current){ ensureCapacity(); data[current] = (Integer)data[(current - 1)] + random.nextInt(5); sb.append("," + data[current]); } System.out.println(sb.length() > 0 ? sb.toString() : ""); } /** * 初始化指定大小的升序顺序表 * @param size */ public void initacs(int size){ ensureCapacity(); StringBuffer sb = new StringBuffer(); Random random = new Random(); data[0] = 1; System.out.print(data[0]); for(current = 1; current < size; ++current){ ensureCapacity(); data[current] = (Integer)data[(current - 1)] + 1 + random.nextInt(5); sb.append("," + data[current]); } System.out.println(sb.length() > 0 ? sb.toString() : ""); } /** * 初始化指定大小的降序顺序表 * @param size */ public void initDecs(int size){ StringBuffer sb = new StringBuffer(); for(current = 0; current < size; ++current){ ensureCapacity(); data[current] = size - current; sb.append("," + data[current]); } System.out.println(sb.length() > 0 ? sb.substring(1) : ""); } /** * 返回顺序表的遍历数据 * @return string a[0],a[1],...,a[n] */ public String toString(){ StringBuffer sb = new StringBuffer(); for(int i = 0; i < this.current; ++i){ sb.append("," + this.data[i]); } if (sb.length() > 0) { return sb.substring(1); } return ""; } //主方法测试 public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); //创建arrayList // for (int i = 1; i <= 22; i++) { // list.add(i); // } // list.removeToIndex(0); // list.add(2, 1); // list.removeToIndex(list.size()); //遍历list数组 // for (int i = 0; i < list.size(); i++) { // System.out.println(list.get(i)); // } // list.initRamdomList(20); // list.initacs(10); list.initDecs(20); list.remove(); System.out.println(list.toString()); } }