JAVA集合框架——List

版权声明:转载请注明来源! https://blog.csdn.net/qq_19595957/article/details/85160728

List介绍

list集合可以装任意类型,里面的数据有序且可以重复

List体系结构

在这里插入图片描述

ArrayList

底层基于数组的(数组在内存中是一块连续的内存),查询和修改数据较快(索引维护的),删除和插入较慢(需要移动内存)

手写ArrayList简单版

import java.util.Arrays;

/**
 * @author maple
 *使用泛型
 *创建ArrayList对象时,如果没有指定长度,默认长度为16
 * @param <T>
 */
public class ArrayList<T> {
	/**数据*/
	private T[] datas = null;
	/**数组下标*/
	private int size = 0;
	
	/**
	 * 默认长度
	 */
	public ArrayList() {
		this(16);
	}
	
	/**
	 * 创建时指定长度
	 * @param size
	 */
	public ArrayList(int size) {
		datas = (T[]) new Object[size];
	}
	
	
	/*增加数据*/
	/**
	 * 增加数据
	 * 增加之前先判断数组长度是否够,如果不够进行动态扩容
	 * 动态扩容:增加原长度的百分之30
	 * @param data
	 */
	public void add(T data) {
		//判断是否要扩容
		if (isDilatation(datas.length)) {
			datas = dilatation(datas.length);
		}
		//增加数据
		datas[size++] = data;
	}
	
	/*删除数据*/
	/**
	 * 删除指定位置的数据
	 * @return 返回被删对象
	 */
	public T delete(int index) {
		indexOutOf(index);
		T temp = datas[index];
		System.arraycopy(datas, index+1, datas, index, size-index-1);
		size--;
		return temp;
	}
	
	/**
	 * 判断下标是否越界
	 * 如果越界抛出异常
	 * @param index
	 * @return
	 */
	private void indexOutOf(int index) {
		if (index < 0 || index >= size) 
			throw new ArrayIndexOutOfBoundsException("超出范围!!!");
	}
	
	/*获取*/
	/**
	 * 根据下标获取元素
	 * @param index
	 * @return 返回对象
	 */
	public T get(int index) {
		indexOutOf(index);
		return datas[index];
	}
	
	
	/**
	 * @param data 查询的数据
	 * @param beginIndex 开始下标
	 * @param endIndex 结束下标
	 * @return
	 */
	public int indexOf(T data, int beginIndex, int endIndex) {
		if (data == null) {
			for (int i = beginIndex; i < endIndex; i++) {
				if (datas[i] == null) {
					return i;
				}
			}
		} else {
			for (int i = beginIndex; i < endIndex; i++) {
				if (datas[i].equals(data)) {
					return i; //查找到就返回下标
				}
			}
		}
		
		return -1;//没找到返回-1
	}
	
	/*从前往后查询数据*/
	/**
	 * 从前往后查找,返回第一次出现的数据
	 * 如果没找到返回-1
	 * @param data
	 * @return
	 */
	public int indexOf(T data) {
		/*if (data == null) {
			for (int i = 0; i < size; i++) {
				if (datas[i] == null) {
					return i;
				}
			}
		} else {
			for (int i = 0; i < size; i++) {
				if (datas[i] == data) {
					return i; //查找到就返回下标
				}
			}
		}
		
		return -1;//没找到返回-1
*/		
		return indexOf(data, 0, size);
		}
	
	/*判断数据是否为空*/
	/**
	 * 判断数据是否为空
	 * 如果为空返回true,否则返回false
	 * @return
	 */
	private boolean isEmpty() {
		return size == 0;
	}
	
	
	/*返回数据长度*/
	public int size() {
		return size;
	}
	
	
	/*进行数组扩容*/
	private T[] dilatation(int length) {
		T[] newData = null;
		//进行数组扩容
		newData = (T[]) new Object[(int) (length+length*0.3+1)];
		//将原数组的数据复制到新数组这
		System.arraycopy(datas, 0, newData, 0, length);
		return newData;
	}
	
	/*判断数组是否需要扩容*/
	/**
	 * 判断数组是否需要扩容
	 * 如果需要返回true,不需要返回false
	 * @return
	 */
	private boolean isDilatation(int length) {
		if (size >= length) 
			return true;
		return false;
	}
	
	
	@Override
	public String toString() {
		if (isEmpty())
			return "";
		Object[] newData = new Object[size];
		System.arraycopy(datas, 0, newData, 0, size);
		return Arrays.toString(newData);
	}
}

LinkedList

底层基于双向链表的(不是一块连续的内存),插入和删除较快(只需改变引用即可),查询和修改数据较慢(需要一个个取出来)

手写LinkedList简单版(使用的是单链表,没有用双链表)
/**
 * @author maple
 *节点类
 */
public class Node {
	/**数据*/
	private Object data;
	/**下一节点*/
	private Node next;
	
	public Node(){}
	
	public Node(Object data) {
		this.data = data;
	}
	
	public void setData(Object data) {
		this.data = data;
	}
	
	public Object getData() {
		return data;
	}
	
	public void setNext(Node next) {
		this.next = next;
	}
	
	public Node getNext() {
		return next;
	}
	
	@Override
	public String toString() {
		return this.data.toString();
	}
}


public class LinkedList {
	//首节点
	private Node first;
	
	//元素个数
	private int size;
	
	/**
	 * 增加节点
	 * 增加前判断first是否为null
	 */
	public void add(Object obj) {
		Node node = new Node(obj);
		if (firstEmpty()) {
			first = node;
		} else {
			Node tmp = first;
			while (tmp.getNext() != null) { //找到最后一个节点
				tmp = tmp.getNext();
			}
			tmp.setNext(node);
		}
		
		size++;
	}
	
	/**
	 * 根据指定的下标删除对象
	 * @param index 要删除的下标
	 * @return 返回删除的对象
	 */
	public Object delete(int index) {
		indexOutOf(index);
		int count = 0;
		if (firstEmpty()) {
				throw new RuntimeException("超出范围!!!");
		}
		Node tmp = first;
		Node pre = null;
		Node result = null;
		while (tmp.getNext() != null) { //拿到最后一个元素
			if (count == index-1) {
				pre = tmp;
				result = pre.getNext();
				pre.setNext(tmp.getNext().getNext());
				size--;
				break;
			}
			count++;
			tmp = tmp.getNext();
		}
		return result;
	}
	
	
	/**
	 * 根据查找的元素返回下标
	 * @param obj 元素
	 * @return 如果找到了返回下标,如果没找到返回-1
	 */
	public int indexOf(Object data) {
		int count = 0;
		if (firstEmpty()) {
			throw new RuntimeException("超出范围!!!");
		}
		
		Node tmp = first;
		while (tmp != null) {
			if (tmp.getData().equals(data)) {
				return count;
			}
			tmp = tmp.getNext();
			count++;
		}
		
		return -1;
	}
	
	/**
	 * 根据指定的下标查找元素
	 * @return 如果找到了就返回对象,如果找不到就返回null
	 */
	public Object get(int index) {
		indexOutOf(index);
		int count = 0;
		if (firstEmpty()) {
			throw new RuntimeException("超出范围!!!");
		}
		
		Node tmp = first;
		while (tmp.getNext() != null) { //拿到最后一个元素
			if (count == index)
				break;
			count++;
			tmp = tmp.getNext();
		}
		return tmp;
	}
	
	/**
	 * 判断下标是否越界
	 * 如果越界抛出异常
	 * @param index
	 * @return
	 */
	private void indexOutOf(int index) {
		if (index < 0 || index >= size) {
			throw new RuntimeException("超出范围!!!");
		}
	}
	
	/**
	 * 判断首节点是否为null
	 * @return 如果为null返回true,不为null返回false
	 */
	private boolean firstEmpty() {
		return first == null;
	}
	
	
	/**
	 * 返回元素个数
	 * @return
	 */
	public int size() {
		return size;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("LinkedList:[");
		Node tmp = first;
		if (firstEmpty()) {
			sb.append("]");
		} else {
			while (tmp.getNext() != null) {
				sb.append(tmp.getData()+",");
				tmp = tmp.getNext();
			}
			sb.append(tmp.getData());
		}
		sb.append("]");
		return sb.toString();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_19595957/article/details/85160728