Java集合

参考原博

集合架构


集合与数组的区别

长度内容元素
数组固定基本类型或引用类型同一种类型
集合可变引用类型可以存储不同类型(一般存储同种类型)

Collection集合的方法

集合分类

  • Collection 接口的接口 对象的集合(单列集合)
    ├ —— List 接口:元素按进入先后有序保存,可重复
    │—————├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
    │—————├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
    │—————└ Vector 接口实现类 数组, 同步, 线程安全
    └ ———————└ Stack 是Vector类的实现类
    ├ —— Set 接口: 仅接收一次,不可重复,并做内部排序
    ├ —————└ HashSet 使用hash表(数组)存储元素
    │———————└ LinkedHashSet 链表维护元素的插入次序
    └ —————└ TreeSet 底层实现为二叉树,元素排好序
    ├ —— Queue接口:
    └ —————└ LinkedList 接口实现类(窄化了对LinkedList的方法的访问权限)

  • Map 接口 键值对的集合 (双列集合)
    ├——— Hashtable 接口实现类, 同步, 线程安全
    ├——— HashMap 接口实现类 ,没有同步, 线程不安全
    │—————–├ LinkedHashMap 双向链表和哈希表实现LinkedHashMap详解 分析LinkedHashMap了解LRU
    └ ————— └ WeakHashMap
    ├ ——–TreeMap 红黑树对所有的key进行排序
    └ ——– IdentifyHashMap

List和Set

1. List和Set区别

有序性唯一性元素获取功能
list按插入顺序排序元素可以重复可通过索引获取查找效率高,插入删除效率低(元素位置改变)
set存储和取出顺序不一致元素唯一不能通过索引查找效率低,插入删除效率高

2. List

3. Set

  • HashSet底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。
  • LinkedHashSet底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。
  • TreeSet底层数据结构采用二叉树来实现,元素唯一且已经排好序;唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性(comparable 和 comparator)。

4. 如何使用

Map

  • Map 没有继承 Collection 接口
  • key 不能重复(由set实现),value可以重复(由Collection实现) 。

方法

HashMap,HashTable,ConccurentHashMap

HashMap:

  • Java8以前:拉链法(数组+链表);最坏情况下,所有元素hash值一样,性能从O(1)转为O(n)
  • Java8及以后:数组+链表+红黑树;当某一链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间,由O(n)转为O(logn)
  • Collections.synchronizedMap(hashMap):将hashmap包装成线程安全
  • 仅有hashmap允许key,value为null
  • getOrDefault(key, value):如果map中有key,则返回key对应的value值,否则,在map中添加(key, value)键值对

HashTable:

  • 线程安全(锁住整个对象),串行执行,效率低
  • 实现:数组 + 链表

ConccurentHashMap:

  • Java8之前:采用segment分段锁(HashTable锁细粒度化)
  • Java8:CAS + synchronized使锁更细化,synchronized只锁定头节点(实现—数组+链表+红黑树)

pub方法:

  1. 判断Node[]数组是否初始化,没有则进行初始化操作
  2. 通过hash定位数组的索引坐标,是否有Node节点,如果没有则使用CAS进行添加(链表的头节点),添加失败则进入下次循环
  3. 检查内部是否正在扩容,帮助一块扩容
  4. 如果插入元素不为null,则使用synchronized锁住该元素(链表/红黑二叉树的头元素)
  5. 判断链表长度是否到达临界值(默认为8)

CAS + synchronized:

  • 首先使用无锁操作CAS插入头节点,失败则循环重试
  • 若头结点已存在,则尝试获取头节点的同步锁,再进行操作

TreeMap

Queue

1. LinkedList

  • linkedList为双链表,维护的是一个first和last指针

LinkedList类中定义了三个变量

  • size:集合的长度
  • first:双向链表头部节点
  • last:双向链表尾部节点

常用方法

  • get(int index):实现机制–比较传入的索引参数index与集合长度size/2,如果是index小,那么从第一个顺序循环;如果index大,那么从最后一个倒序循环
  • add(E e) 和 add(int index, E element)
  • remove(Object o) 和 remove(int index)

特有方法:

  • LinkedList< Integer > list = new LinkedList<>();(前面必须是 LinkedList;List没有这些方法)
  • addFirst()
  • addLast()
  • removeFirst()
  • removeLast()
  • getFirst()
  • getLast()

2. queue

  • Queue queue = new LinkedList();
  • add(), offer(): 前者当队列满时,抛出异常,后者返回false
  • remove(), polI(): 返回第一个并删除;前者当队列空时,抛出异常,后者返回null
  • element(), peek(): 返回第一个;前者当队列空时,抛出异常,后者返回null

3. PriorityQueue

  • PriorityQueue是一个基于堆(二叉小顶堆)的无界队列;优先级队列的元素按照自然顺序或者根据构造队列时提供的Comparator进行排序
  • 不允许使用 null 元素也不允许插入不可比较的对象(没有实现Comparable接口的对象)
  • 头指排指向最小元素

常用方法

  • add():插入,同时调整堆结构(保持小/大顶堆)
  • peek():获取堆顶元素
  • poll():删除堆顶元素,同时调整堆结构
  • size()
  • isEmpty()
//比较map中的value值
HashMap<Integer, Integer> map = new HashMap<>();
PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
	@Override
	public int compare(Integer o1, Integer o2) {
		return map.get(o1) - map.get(o2);
	}
    }):

补充知识点

1. hashCode 与 equals

Java集合中本质是散列表的类,如HashMap,Hashtable,HashSet,通过hashCode 与 equals保证元素唯一:

  • 新加入对象,先比较hashcode值
  • 如果冲突,再通过equals比较

为什么重写equals时必须重写hashCode方法:

  • 如果两个对象相等,那么它们的hashCode()值一定相同,这里的相等是通过equals()比较两个对象返回true确定的,如果不覆盖hashCode方法,修改的equals无效

2. Comparable和Comparator的区别

Comparable:内部比较器

  • int compareTo(Object o)

Comparator:外部比较器

  • int compare(Object o1, Object o2)
  • return o1 - o2 是升序,return o2 - o1 是降序(当方法的返回值大于0的时候就将数组的前一个数和后一个数做交换)
  • 如果类在设计时没有实现内部比较器,后期可以在不用修改原代码的同时实现比较
// Comparator<Integer>():<>中的数据类型取决于arrayList中的数据类型,int 与 Integer 不能混乱
Collections.sort(arrayList, new Comparator<Integer>() {
	@Override
	 public int compare(Integer o1, Integer o2) {
	 	return o2.compareTo(o1);
	 }
});

object.compareTo():

  • Integer: return (x < y) ? -1 : ((x == y) ? 0 : 1);
  • Character: return x - y;
  • String: 依次比较每个字符(x - y)

3. Collections

  • Collections是集合类(Collection)的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序,搜索以及线程安全等各种操作
  • Collections.sort(list):默认升序
  • Collections.shuffling(list):混排,随机打乱
  • Collections.reverse(list):反转
  • Collections.fill(list, ‘a’):使用指定元素替换列表中的所有元素
  • Collections.copy(list_a, list_b):前一个是目标列表,后一个是源列表
  • Collections.min(list)
  • Collections.max(list)
  • Collections.lastIndexOfSubList(list_a, list_b):返回列表中最后一次出现指定目标列表的起始位置
  • Collections.indexOfSubList(list_a, list_b):第一次
  • Collections.rotate(list, 1):根据指定的距离循环移动列表元素,可以是负数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值