003_Java 集合框架

Java集合框架主要分为两大类:Collection(集合)和Map(映射),集合作为数组的补充,能够存储多种数据类型,并支持动态扩容

Map(键值对集合)

  • key全局唯一​​,允许键为null(TreeMap除外)
通用场景​​:首选HashMap
​​并发环境​​:ConcurrentHashMap
​​需要保持插入顺序​​:LinkedHashMap
​​需要排序​​:TreeMap

HashMap

  • 基于哈希表实现,不保证元素的顺序
  • 内部查询原理:
    在这里插入图片描述
JDK1.8之前,采用Node(单链表)数组来存储元素
当hash碰撞的元素较多时,通过key查找value时遍历Node链表的时间复杂度为O(N),查询效率越来越低

Node(单链表)是HashMap的一个内部类,实现了Map.Entry接口,本质是就是一个映射(键值对),其本身包含了:KEY、VALUE、键的hash、下一个Node节点

JDK1.8开始,采用单链表+红黑树(切换阈值8)数组来存储元素。
当链表长度超过8时,将单链表转换为红黑树,通过红黑树查询元素的时间复杂度为O(logN),大大提升查找效率

TreeNode(红黑树)是HahsMap的一个内部类,实现了LinkedHashMap.Entry接口,其本身包含:父节点、左子树、右子树、上一个同级节点、属性颜色

  • 扩容原理:
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
    // 默认初始容大小:1的二进制向左位移4位,即00000001向左位移4位后00010000,转化成十进制为1乘以2的4次方等于16
	static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 
	// 最大容量
	static final int MAXIMUM_CAPACITY = 1 << 30;
	// 加载因子,当存储的元素个数大于数组长度乘以加载因子时触发扩容
	static final float DEFAULT_LOAD_FACTOR = 0.75f;
	// 链表转成红黑树的阈值
	static final int TREEIFY_THRESHOLD = 8;
	// 红黑树转为链表的阈值
	static final int UNTREEIFY_THRESHOLD = 6;
	// 最小树形化容量阈值:当哈希表中的容量 > 该值时才允许树形化链表(即将链表转换成红黑树)
    // 否则,若桶内元素太多时,则直接扩容,而不是树形化
	static final int MIN_TREEIFY_CAPACITY = 64;
	
	// key的哈希算法
	static final int hash(Object key) {
        int h;
        // key的hash值对容器大小进行取模运算,运算结果决定了当前key所属数组的下标
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

在这里插入图片描述

加载因子是HashMap在其容量自动增加之前可以达到多满的一种尺度。
负载因子越大表示散列表的装填程度越高,对空间的利用更充分,但查找效率会降低;
负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费,但查询效率会提升
当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值(数组的长度乘以加载因子)就要自动扩容,大小为原来的2倍

LinkedHashMap

  • 继承自HashMap,内部维护一个双向链表来记录元素的插入顺序

TreeMap

  • 基于红黑树实现,按照键的自然顺序或指定的比较器顺序进行排序
  • 提供了丰富的导航方法(如firstKey, lastKey, headMap, tailMap等)
public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
  • 自定义排序
TreeMap<String,Object> treeMap = new TreeMap<String,Object>(Comparator.reverseOrder());
treeMap.put("a", "a");
treeMap.put("b", "b");
treeMap.put("c", "c");
// {"c":"c","b":"b","a":"a"} 倒叙排列
System.out.println(JSON.toJSONString(treeMap));
TreeMap<String,Object> treeMap = new TreeMap<String,Object>(Comparator.naturalOrder());
treeMap.put("b", "b");
treeMap.put("a", "a");
treeMap.put("c", "c");
// {"a":"a","b":"b","c":"c"} 正序排列
System.out.println(JSON.toJSONString(treeMap));

Collection

在这里插入图片描述

List 接口(有序、可重复)

ArrayList

  • ArrayList类内部使用Object数组存储元素,Vector和ArrayList类似,只是其内部方法都添加了synchronized关键字
  • ArrayList实现了RandomAccess接口,该接口提供了通过索引快速查找元素的能力【适合做查询操作】
  • 自定义排序
List<String> stringList = new ArrayList<>();
stringList.add("a");
stringList.add("c");
stringList.add("b");
// TODO 默认升序排列 ["a","b","c"]
stringList.sort(Comparator.naturalOrder());
// TODO 倒序排列 ["c","b","a"]
stringList.sort(Comparator.reverseOrder());
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 20));
studentList.add(new Student("李四", 22));
studentList.add(new Student("王五", 24));
studentList.sort(new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return o2.getAge() - o1.getAge(); // 倒序
    }
});

LinkedList

  • LinkedList类内部使用Node链表存储元素,每个节点除了包含存储自身数据外,还存储前、后两个节点的引用
  • LinkedList实现了Deque接口,该接口提供了从集合两端进行队列操作的能力【适合做添加、删除操作】

Set接口

HashSet(无序、不重复)

  • HashSet是通过HashMap实现元素去重,存储的元素是

LinkedHashSet(有序、不重复)

  • LinkedHashSet继承HashSet类,内通过一个单链表来记录添加元素时的顺序,所以存储的元素是

TreeSet

  • 自定义排序
TreeSet<String> treeSet = new TreeSet<String>(Comparator.naturalOrder());
treeSet.add("c");
treeSet.add("a");
treeSet.add("b");
// ["a","b","c"] 正序排列
System.out.println(JSON.toJSON(treeSet));
TreeSet<String> treeSet = new TreeSet<String>(Comparator.reverseOrder());
treeSet.add("c");
treeSet.add("a");
treeSet.add("b");
// ["c","b","a"] 倒序排列
System.out.println(JSON.toJSON(treeSet));
TreeSet<Student> treeSet = new TreeSet<Student>(new Comparator<Student>() {
	@Override
	public int compare(Student o1, Student o2) {
	    // 按照年龄倒叙
	    return o2.getAge() - o1.getAge();
	}
});
treeSet.add(new Student("张三", 20));
treeSet.add(new Student("李四", 22));
treeSet.add(new Student("王五", 24));
// [{"name":"王五","age":24},{"name":"李四","age":22},{"name":"张三","age":20}] 倒序排列
System.out.println(JSON.toJSON(treeSet));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大能嘚吧嘚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值