所有List接口的实现类都具有list接口的特点 : 有序可重复
- ArrayList:
- 底层:可变数组(数组在内存中分配连续的内存空间)
- 特点:
- 优点:根据索引遍历|获取效率高
- 缺点:做增删效率低
- 扩容:通过copyof方法进行动态扩容,每次扩容原容量的1.5倍
- 适合用于大量查询少量增删情况
- Vector:
- 与ArrayList类似,底层使用数组
- 区别:
- 1)Vector线程安全的 ArrayList线程不安全
- 2)Vector每次扩容原容量的2倍,ArrayList每次扩容原容量的1.5倍
- LinkedList:
- 底层: 使用双向链表实现
- 优点: 插入删除效率高
- 查询: 查询效率低
- 适合用于大量增删少量查询的情况
- 新增了一些操作链表头尾的方法
public class ListDemo05 {
public static void main(String[] args) {
List<Person> ls = new ArrayList(); //内部创建换一个数组是默认空数组
ls.add(new Person("zhangsan",18));
//第一次添加创建一个大小10的数组,后续添加如果大小不够>10,会进行扩容
System.out.println(ls.size());
}
}
LinkedList:使用单向链表简单实现
- 数据都是以节点为单位
- 单向链表: 节点: 数据值 下一个节点的地址
- 双向链表: 节点: 上一个节点的地址 数据值 下一个节点的地址
public class MyLinkedList01 {
public static void main(String[] args) {
MyLinkedList my = new MyLinkedList();
my.add("张三");
my.add("李四");
my.add("王五");
System.out.println(my.size());
System.out.println(my.get(0));
System.out.println(my.get(1));
System.out.println(my.get(2));
}
}
//自定义容器类
class MyLinkedList{
//记录链表头节点
private Node head;
//记录容器中数据的个数(节点的个数)
private int size;
public MyLinkedList() {
}
public Object get(int index) {
if(index<0 || index>=size) {
throw new ArrayIndexOutOfBoundsException(index);
}
Node temp = head; //永远为当前节点
for(int i=0;i<size;i++) {
if(i==index) {
return temp.getData();
}
temp = temp.getNext();
}
return null;
}
public void add(Object value) {
//只要调用add方法,就添加一个新的数据,就是一个新节点
Node node = new Node(value,null);
//把新节点添加到结构最后位置
//1)如果链表头节点为null,当前构建的新节点作为链表头存在
if(head == null) {
head = node;
}else {
//2)已存在链表头节点,找到最后一个节点,新节点的地址赋值给原链表最后节点的next属性
Node temp = head;
while(temp.getNext()!=null) {
temp = temp.getNext();
}
temp.setNext(node);
}
size++;
}
public int size() {
return this.size;
}
}
//单向链表: 节点: 数据值 下一个节点的地址
class Node{
private Object data; //数据值
private Node next; //下一个节点地址
public Node() {
// TODO Auto-generated constructor stub
}
public Node(Object data, Node next) {
super();
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}