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