1. LinkedList
1.1 LinkedList 实现
LinkedList 底层为双向链表,双向链表每个结点使用 Node<E> 结构,通过 prev 和 next 指向前后结点,链表头使用 LinkedList<E> 结构,通过 first 和 last 指向链表头和连表尾,即链表的第一个元素和最后一个元素。
1.1.1Node 结构
class Node<E> {
Node<E> prev; // 前结点引用
E e; // 存储元素
Node<E> next; // 后结点引用
}
1.1.2 LinkedList
class LinkedList<E> {
Node<E> first; // 头结点引用
Node<E> last; // 尾结点引用
int size; // 有效元素个数
}
// size 为 int 类型数据,因此 Java 规定链表结点个数最大为 Integer.MAX_VALUE
1.2 常用方法
LinkedList 遵从 List 接口,List 接口中所有方法都可以使用
addE e); 在链表末尾添加元素
public boolean add(E e) {
MyNode<E> node = new MyNode<>(e);
if (null == last) {
first = node;
} else {
last.setNext(node);
node.setPrev(last);
}
last = node;
size += 1;
return true;
}
addLast(E e); 在链表末尾添加元素
public void addLast(E e) {
add(e); // 可以直接使用 add(E e)
}
addFirst(E e); 在链表头添加元素
public void addFirst(E e) {
if (null == first) {
add(e); // 为空时相当于在表尾插入元素,可以使用 add(E e)
} else {
MyNode<E> node = new MyNode<>(e);
first.setPrev(node);
node.setNext(first);
first = node;
size +=1;
}
}
E getLast(); 获取链表尾对应的元素
public E getLast() {
return last != null ? last.getE() : null;
}
E getFirst(); 获取链表头对应的元素
public E getFirst() {
return first != null ? first.getE() : null;
}
E removeFirst(); 删除表尾元素,并且返回值是存储的元素对象
public E removeFirst() {
E e = null;
if (size > 1) {
final MyNode<E> temp = first;
first = temp.getNext();
first.setPrev(null);
temp.setNext(null);
size -= 1;
e = temp.getE();
} else if (1 == size) {
e = first.getE();
first = null;
last = null;
size -= 1;
}
return e;
}
E removeLast(); 删除表头元素,并且返回值是存储的元素对象
public E removeLast() {
E e = null;
if (size > 1) {
final MyNode<E> temp = last;
last = temp.getPrev();
last.setNext(null);
temp.setPrev(null);
e = temp.getE();
size -= 1;
} else if (1 == size) {
e = last.getE();
first = null;
last = null;
size -= 1;
}
return e;
}
1.3 LinkedList 性能分析
LinkedList 底层是一个带有链表头结构的双向链表,因此在头结点和尾结点进行【增删改查】操作小笼包极高,其他结点因为空间不连续的问题,需要逐一进行循环遍历,导致效率较低
2. Map
2.1 Map存储结构
Map不能创建对象,可以通过多态的形式创建对象,Map中有两个参数,K 表示键,V 表示值,一个键有且对应一个值,即所谓的键值对。Map 中不能包含重复的键,重复添加则会进行覆盖,保存最后一次添加。
数据存储方式(键值对)
<K, V>
K ==> Key 键(不可重复)
V ==> Value 值
2.2 常用方法
2.2.1 构造方法
HashMap(); 用于实例化 HashMap 对象
HashMap(int initCapacity); 根据用户指定的底层键值对个数/容量,实例化 HashMap 对象
2.2.2 成员方法
增 put(K k, V v);
Map<String, String> map = new HashMap<>();
map.put("001","张三");
删
V remove(Object k);
void remove(Object k, Object v);
clear();
String str = map.remove("张三");
System.out.println(map);
改 put(K k, V v);
改操作和增加操作是一样的,使用 put 方法进行数据覆盖,完成改操作
查 int size(); 集合中键值对的个数
boolean isEmpty(); 判断是否为空
boolean containsKey(Object key); 判断集合是否包含指定的键
boolean containnsValue(Object value); 判断集合是否包含指定的值
V get(Object k); 根据键获取键所对应的值
Collection values(); 获取所有值的集合
Set keySet(); 获取所有键的集合
Set<Map,Entry<K,V>> entrySet(); 获取所有键值对对象集合
2.3 Entry
Entry 底层结构
Entry 是 Map 结构的内部数据类型,使用的泛型是延续 Map 声明的情况。Entry 是【键值对模型】。在 Map 中存储的键值对数据其实都是一个又一个的 Entry,Map 提供了方法将 Map 底层的 Entry 对象返回提供给程序员使用
class Entry<K, V> {
K k;
V v;
K getKey() {
return k;
}
V getValue() {
return v;
}
}