java集合框架

关于容器类的简单学习,后续还会修改~

首先插入一张图

有图可见java集合框架主要分为collection 和Map两大接口及其子类

collection


list

list是一个元素有序,可以重复(list的数据结构就是一个序列,新建时直接在内存中开辟一块连续的内存,将空间地址与索引对应,存储时彼此不会有影响),并且可以为null的集合。

list的equals方法默认和==一致,比较的时地址,所以需要从写放入list中的类的  equals和hashCode方法

 List.subList 方法并没有像我们想的那样:创建一个新的 List,而是与原来的list公用一个引用,只是改了 offset 和 size,可有以下列子论证:

list与array

相似之处: 都可以表示一组同类型的对象 ;都使用下标进行索引

不同之处: 数组可以存任何类型元素;list 不可以存基本数据类型,必须要包装数组容量固定不可改变;List 容量可动态增长数组效率高; List 由于要维护额外内容,效率相对低一些


arraylist

本质是一个object类型的数组所以元素可以为null,



只是可以扩容(初始值为10),当size<6时直接增加到12否则变为1.5倍


由于arraylist不是线程安全所以并发时会引发迭代器的快速失败,因此需要在并发时加锁,

List list = Collections.synchronizedList(new ArrayList(...));

linkedlist

可以实现栈,队列

本质是一个链表,不存在容量限制

相对于arraylist更非空间,因为要维护链表结构

元素是有序的,输出顺序与输入顺序一致

允许元素为 null

所有指定位置的操作都是从头开始遍历进行的

和 ArrayList 一样,不是同步容器


linkedList与arrayList主要从以下四点比较

1、查找速度     2、修改速度    3、容量        4、内存开销


Vector

线程安全类型的ArrayList(其实还是有差别的)

Vector 特点

  • 底层由一个可以增长的数组组成
  • Vector 通过 capacity (容量) 和 capacityIncrement (增长数量) 来尽量少的占用空间
  • 扩容时默认扩大两倍
  • 最好在插入大量元素前增加 vector 容量,那样可以减少重新申请内存的次数
  • 通过 iterator 和 lastIterator 获得的迭代器是 fail-fast 的
  • 通过 elements 获得的老版迭代器 Enumeration 不是 fail-fast 的
  • 同步类,每个方法前都有同步锁 synchronized
  • 在 JDK 2.0 以后,经过优化,Vector 也加入了 Java 集合框架大家族

与ArrayList比较

共同点:

  • 都是基于数组
  • 都支持随机访问
  • 默认容量都是 10
  • 都有扩容机制

区别:

  • Vector 比 ArrayList 多一种迭代器 Enumeration
  • Vector 是线程安全的,ArrayList 不是
  • Vector 默认扩容 2 倍,ArrayList 是 1.5

如果没有线程安全的需求,一般推荐使用 ArrayList,而不是 Vector,因为每次都要获取锁,效率太低。


set

基于map实现的

hashSet

无序块

treeSet

有序,效率相对较低

linkedHashSet

结合前两者,有序,效率只比hashset差点




queue

队列:尾部添加,头部删除,类似于生活中的排队。

单队列:会出现假溢出

循环队列:

queue:用来存放 等待处理元素 的集合,这种场景一般用于缓冲、并发访问。除了继承 Collection 接口的一些方法,Queue 还添加了额外的 添加、删除、查询操作(实现队列的方法)。

Map(与collection同一等级)

其实就是键值对 (key-value) 的映射


keyset:是map中键的集合,是一个set集合所以不能重复

values:是map中值得集合,是collection所以可以重复,(但是set也是collection,所以有点不解,猜测应该是指list

entry:表示一组映射,map中的entry是一个set的集合。

由map的结构组成便有三个遍历的方法:

由key间接遍历值

Set<T> strings = m.keySet();
        Iterator<String> iterator = strings.iterator();
        while(iterator.hasNext()){
            System.out.println(m.get(iterator.next()));
        }

由value直接遍历得到值

Collection<T> values = m.values();
        Iterator<T> iterator = values.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

由entry得到键值对集合,遍历该集合得到值

Set<Map.Entry<T, T>> entries = m.entrySet();
        for (Map.Entry<T, T> entry : entries) {
            System.out.println(entry.getValue());
        }

HashTable

古老线程安全

HashMap(默认大小为16,加载因子为0.75)

  • 底层实现是 链表数组(Node<K,V>[] table),JDK 8 后又加了 红黑树
  • 实现了 Map 全部的方法
  • key 用 Set 存放,所以想做到 key 不允许重复,key 对应的类需要重写 hashCode 和 equals 方法
  • 允许空键和空值,放在第一(计算hash值时直接返回0)
  • 元素是无序的,而且顺序会不定时改变
  • 插入、获取的时间复杂度基本是 O(1)(前提是有适当的哈希函数,让元素分布在均匀的位置)
  • 遍历整个 Map 需要的时间与 桶(数组) 的长度成正比(因此初始化时 HashMap 的容量不宜太大)
  • 两个关键因子:初始容量、加载因子

Hashtable除了不能为null以及是线程同步几乎和hashmap一样

TreeMap

有序(基于元素的固有顺序 ,由 Comparator 或者 Comparable 确定),效率较低

LinkedHashMap

结合了hashmap与treemap  有序(基于元素进入集合的顺序或者被访问的先后顺序排序)并且效率也不错只是比hashmap慢一点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值