• 理解java容器底层原理--手动实现ArrayList


    为了照顾初学者,我分几分版本发出来

    版本一:基础版本

     实现对象创建、元素添加、重新toString() 方法

    package com.xzlf.collection;
    
    /**
     * 自定义一个ArrayList,体会底层实现原理
     * 初始版本
     * @author xzlf
     *
     * @param <E>
     */
    public class MyArrayList<E> {
    	private Object[] elementDate;
    	private int size;
    	private static final int DEFAULT_CAPACITY = 10;
    	
    	public MyArrayList() {
    		elementDate = new Object[DEFAULT_CAPACITY];
    	}
    	
    	public MyArrayList(int capacity) {
    		elementDate = new Object[capacity];
    	}
    	
    	public void add(E element) {
    		elementDate[size++] = element;
    	}
    	
    	
    	@Override
    	public String toString() {
    		StringBuilder sb = new StringBuilder("[");
    		for (int i = 0; i < size; i++) {
    			sb.append(elementDate[i] + ",");
    		}
    		sb.setCharAt(sb.length() - 1, ']');
    		return sb.toString();
    	}
    	
    	public static void main(String[] args) {
    		MyArrayList<String> list = new MyArrayList<String>(20);
    		list.add("aa");
    		list.add("bb");
    		list.add("cc");
    		System.out.println(list);
    	}
    }
    

    测试运行

    版本二:增加扩容

    package com.xzlf.collection;
    
    /**
     * 自定义一个ArrayList,体会底层实现原理
     * 增加扩容
     * @author xzlf
     *
     * @param <E>
     */
    public class MyArrayList2<E> {
    	private Object[] elementDate;
    	private int size;
    	private static final int DEFAULT_CAPACITY = 10;
    	
    	public MyArrayList2() {
    		elementDate = new Object[DEFAULT_CAPACITY];
    	}
    	
    	public MyArrayList2(int capacity) {
    		elementDate = new Object[capacity];
    	}
    	
    	public void add(E element) {
    		// 元素个数等于数组长度时 进行扩容操作
    		if(size == elementDate.length) {
    			Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
    			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
    			elementDate = newArray;
    		}
    		elementDate[size++] = element;
    	}
    	
    	
    	@Override
    	public String toString() {
    		StringBuilder sb = new StringBuilder("[");
    		for (int i = 0; i < size; i++) {
    			sb.append(elementDate[i] + ",");
    		}
    		sb.setCharAt(sb.length() - 1, ']');
    		return sb.toString();
    	}
    	
    	public static void main(String[] args) {
    		MyArrayList2<String> list = new MyArrayList2<String>();
    		for (int i = 0; i < 15; i++) {
    			list.add("aa" + i);
    		}
    		System.out.println(list);
    	}
    }
    

    测试:

    版本三:添加get set方法以及数组边界检查

    package com.xzlf.collection;
    
    /**
     * 增加get set 方法
     * 增加数组边界检查
     * @author xzlf
     *
     * @param <E>
     */
    public class MyArrayList3<E> {
    	private Object[] elementDate;
    	private int size;
    	private static final int DEFAULT_CAPACITY = 10;
    	
    	public MyArrayList3() {
    		elementDate = new Object[DEFAULT_CAPACITY];
    	}
    	
    	public MyArrayList3(int capacity) {
    		if(capacity < 0) {
    			throw new RuntimeException("数组容量不能为负数");
    		}else if(capacity == 0) {
    			elementDate = new Object[DEFAULT_CAPACITY];
    		}
    		elementDate = new Object[capacity];
    	}
    	
    	public void add(E element) {
    		// 元素个数等于数组长度时 进行扩容操作
    		if(size == elementDate.length) {
    			Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
    			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
    			elementDate = newArray;
    		}
    		elementDate[size++] = element;
    	}
    	
    	
    	public E get(int index) {
    		checkRange(index);
    		return (E) elementDate[index];
    	}
    	
    	public void set(E element, int index) {
    		checkRange(index);
    		elementDate[index] = element;
    	}
    	
    	public void checkRange(int index) {
    		// 索引合法判断[0,size)
    		if(index < 0 || index > size -1) {
    			throw new RuntimeException("索引不合法:" + index);
    		}
    	}
    	@Override
    	public String toString() {
    		StringBuilder sb = new StringBuilder("[");
    		for (int i = 0; i < size; i++) {
    			sb.append(elementDate[i] + ",");
    		}
    		sb.setCharAt(sb.length() - 1, ']');
    		return sb.toString();
    	}
    	
    	public static void main(String[] args) {
    		MyArrayList3<String> list = new MyArrayList3<String>();
    		for (int i = 0; i < 15; i++) {
    			list.add("aa" + i);
    		}
    		System.out.println(list);
    		System.out.println(list.get(10));
    		list.set("bb", 10);
    		System.out.println(list.get(10));
    		System.out.println(list.get(-10));
    	}
    }
    

    测试:

    版本四:增加remove、size、isEmpty

    package com.xzlf.collection;
    
    /**
     * 增加remove()
     * 增加size isEmpty
     * @author xzlf
     *
     * @param <E>
     */
    public class MyArrayList4<E> {
    	private Object[] elementDate;
    	private int size;
    	private static final int DEFAULT_CAPACITY = 10;
    	
    	public MyArrayList4() {
    		elementDate = new Object[DEFAULT_CAPACITY];
    	}
    	
    	public MyArrayList4(int capacity) {
    		if(capacity < 0) {
    			throw new RuntimeException("数组容量不能为负数");
    		}else if(capacity == 0) {
    			elementDate = new Object[DEFAULT_CAPACITY];
    		}
    		elementDate = new Object[capacity];
    	}
    	
    	public void add(E element) {
    		// 元素个数等于数组长度时 进行扩容操作
    		if(size == elementDate.length) {
    			Object[] newArray = new Object[elementDate.length + (elementDate.length >> 1)];
    			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
    			elementDate = newArray;
    		}
    		elementDate[size++] = element;
    	}
    	
    	
    	public E get(int index) {
    		checkRange(index);
    		return (E) elementDate[index];
    	}
    	
    	public void set(E element, int index) {
    		checkRange(index);
    		elementDate[index] = element;
    	}
    	
    	public void checkRange(int index) {
    		// 索引合法判断[0,size)
    		if(index < 0 || index > size -1) {
    			throw new RuntimeException("索引不合法:" + index);
    		}
    	}
    	
    	public void remove(int index) {
    		int numMoved = size - index -1;
    		if(numMoved > 0) {
    			System.arraycopy(elementDate, index+1, elementDate, index, numMoved);
    		}
    		elementDate[--size] = null;
    	}
    	
    	public void remove(E element) {
    		// 遍历所有元素,和传入的element比较,获取第一个为true的位置 删除
    		for (int i = 0; i < size; i++) {
    			if(element.equals(get(i))) {
    				remove(i);
    			}
    		}
    	}
    	
    	public int size() {
    		return size;
    	}
    	
    	public boolean isEmpty() {
    		return size == 0;
    	}
    	@Override
    	public String toString() {
    		StringBuilder sb = new StringBuilder("[");
    		for (int i = 0; i < size; i++) {
    			sb.append(elementDate[i] + ",");
    		}
    		sb.setCharAt(sb.length() - 1, ']');
    		return sb.toString();
    	}
    	
    	public static void main(String[] args) {
    		MyArrayList4<String> list = new MyArrayList4<String>();
    		for (int i = 0; i < 15; i++) {
    			list.add("aa" + i);
    		}
    		System.out.println(list);
    		list.remove("aa7");
    		System.out.println(list);
    		list.remove(3);
    		System.out.println(list);
    		System.out.println(list.size());
    		System.out.println(list.isEmpty());
    	}
    }
    

    测试:

    重视基础,才能走的更远。
  • 相关阅读:
    python的函数
    Python的条件语句和循环语句
    Python的输入与输出
    Python变量和类型
    Python的运算符
    Python的注释
    pycharm基本使用
    推特史上最大规模黑客入侵案:17岁问题少年的隐秘人生
    进程和线程的区别及线程的介绍
    python接口自动化42
  • 原文地址:https://www.cnblogs.com/xzlf/p/12681543.html
Copyright © 2020-2023  润新知