1. 程式人生 > >JAVA集合框架——List

JAVA集合框架——List

List

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();
	}
}