Loading

Java常用容器基础操作汇总

背景

容器是Java的重要组成部分,在实际应用中选择适当的容器,往往能达到事半功倍的效果。

下图为Java集合框架图,图源于菜鸟教程

Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

从上图中也可以看到,Java的类基本上都继承自Collection和Map。我们平时使用的主要是一些具体实现类,例如ArrayList,LinkedList,HashSet,HashMap等。本文将对这些容器的基础操作进行汇总,以便复习与查阅。

NOTE: 初始化容器时需要注意抽象类(或接口)和具体实现类的区别。抽象类只关心抽象方法的定义,不关心具体如何实现。抽象类不可以实例化对象,也就是说new后面不能接抽象类,而要接具体实现类。否则会引发错误XXX is abstract; cannot be instantiated

二、各类容器

2.1 List

List是一种接口。使用前需要导入java.util.List相关包。
具体实现类有:

  • ArrayList
  • LinkedList
  • Vector
  • Stack:Vector的子类

ArrayList和LinkedList常放在一起比较,两者都是线程不安全的。ArrayList的底层是Object数组,LInkedList的底层结构是双向链表。所以两者本质的区别类似于数组与链表的区别(读取、删除等操作有不同)。

Vector的底层同样是Object数组,是线程安全的,但当前大部分情况都使用ArrayList。

初始化方法

//List 的ArrayList 实现
List<String> list1 = new ArrayList<>();

// List 的LinkedList 实现
List<String> list2 = new LinkedList<>();

// Stack对象创建
Stack<Integer> stk = new Stack<>();

NOTE:尖括号里不能用基础数据类型,需要包装。

使用方法

  • ArrayList
// 添加元素
list.add(obj);
list.addAll();
// boolean addAll(Collection c);

// 访问元素,按索引
obj = list.get(index);

// 删除元素,按索引
list.remove(index);

// 删除元素,按内容
list.remove(obj);

// 计算大小
len = list.size()

// 返回元素的索引值
index = list.indexOf(obj);

// 判断是否包含某元素
list.contains();

// 清空
list.clear();

// 判断是否为空
list.isEmpty();
  • LinkedList

ArrayList列举的方法LinkedList都可以用,除此外还有:

public void addFirst(E e)	// 元素添加到头部。
public void addLast(E e)	// 元素添加到尾部。
public E removeFirst()	// 删除并返回第一个元素。
public E removeLast()	// 删除并返回最后一个元素。
  • Stack
// 压栈
stk.push(Object element);

// 弹栈并返回元素
obj = stk.pop();

// 获取顶上元素
obj = stk.peek();

// 判空
stk.isEmpty();
stk.empty();

2.2 Set

Java中常用的Set为HashSet,和List相比较,Set是不允许有重复元素的,每个元素都具有独一无二的值。
另外,HashSet允许存在null值;无序;非线程安全。

初始化方法

HashSet<String> sites = new HashSet<String>();

使用方法

添加、删除、判空、清空都和ArrayList相同。

sites.add(obj); // 添加
sites.remove(obj); // 删除
sites.size(); // 返回大小
sites.isEmpty(); // 判空
sites.contains(obj); // 判断是否包含元素
sites.clear(); // 清空

2.3 Queue

Queue是Java的队列,队列与栈相反,属于“先进先出”的数据表。Queue是接口,不能直接使用。实现Queue接口的类有:

  • LinkedList
  • ArrayDeque
  • PriorityQueue

PriorityQueue比较特殊,属于优先级队列,可以实现大顶堆或小顶堆。默认是小顶堆。但是可以通过自定义比较器实现其他的需求。

以上几种实现类均非线程安全的。Queue还有一些阻塞的实现类,暂时不在本文记录。

初始化方法

// 使用 LinkedList 创建
Queue<String> animal1 = new LinkedList<>();

// 使用 ArrayDeque 创建
Queue<String> animal2 = new ArrayDeque<>();

// 使用 PriorityQueue创建
Queue<String> animal3 = new PriorityQueue<>();
PriorityQueue<Integer> numbers = new PriorityQueue<>();

使用方法

  • LinkedList
// 添加
q.add(obj); // 失败抛异常
q.offer(obj);  // 失败返回false

// 返回并删除队首元素
q.remove();
q.poll(); // 失败返回false

// 获取队首元素
q.peek();

// 判空
q.isEmpty();

// 大小
q.size();
  • PriorityQueue
// 添加
p.offer(obj);

// 返回并删除队首元素
p.poll();

// 获取队首元素
p.peek();

// 如果想要修改默认的小顶堆设置,改为大顶堆,需要重写Comparator的compare方法
// 重写
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
  @Override
  public int compare(Integer o1, Integer o2) {
    return o2 - o1;
  }
});

// 用lambda语法,更简洁
PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);

2.4 Map

Map的实现类常见的有HashMap。

初始化方法

HashMap<Key, Value> numbers = new HashMap<>();

使用方法

// 加入键值对
m.put(key, value);

// 按key获取value
v = m.get(key);

// 返回所有key集合
m.keySet();

// 返回所有value集合
m.values();

// 删除
m.remove(key);
m.remove(key, value);

// 替换
m.replace(key, value);
m.replace(key, oldValue, newValue);

// 判断是否包含key
m.containsKey(key);
// 判断是否包含value
m.containsValue(value);

// 如果要迭代hashmap的话,可以选择迭代key或value
// 通常迭代key会多一些
// 使用for each语句即可,例如
for(int i: map.keySet()) {
  ...
}

参考:

  1. https://www.cainiaojc.com/java/
  2. https://www.runoob.com/java/
posted @ 2022-02-10 15:23  JavicxhloWong  阅读(789)  评论(0编辑  收藏  举报