JAVA集合框架——List
阿新 • • 發佈:2018-12-23
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();
}
}