集合基础和应用

本文深入探讨了Java集合框架中的ArrayList和LinkedList。ArrayList基于数组实现,适合随机访问,尾部添加元素高效;LinkedList采用双向链表,尾部和中间插入效率高,但随机访问性能较差。此外,还介绍了Stack、Queue以及Map接口的实现和特性,如HashMap在JDK1.8中引入红黑树优化。
摘要由CSDN通过智能技术生成

目录

1.集合框架

2.Collection

2.1 ArrayList

2.1.1 基本结构

2.1.2 add方法

2.2 LinkedList

2.2.1 基本结构

 2.2.2 add方法

2.2.3 get方法

链表的随机查找效率很低的,因为需要遍历一半的链表O(n/2)

 3.Stack栈

4.Queue队列

5.1. LinkedList插⼊快? ArrayList, LinkedList 随机插⼊,头尾插⼊效率⽐较?

2.Map

2.1Map继承结构

 2.2JDK1.7版本

2.3 JDK1.8

 3.Set


1.集合框架

Collection接口是所有集合的根,然后扩展开提供了三大类集合,分别是:

  • List,也就是我们前面介绍最多的有序集合,它提供了方便的访问、插入、删除等操作
  • Set,是不允许有重复元素的,这是和List最明显的区别,也就是不存在两个对象equals返回true.我们在日常开发中有很多需要保证元素唯一性的场合。
  • Queue/Deque,则是Java提供的标准队列结构的实现,除了集合的基本功能,它还支持类似先进先出的或者后入先出等行为。

2.Collection

首先ArrayList、Vector、LinkedList集合都是继承了AbstractList抽象类。

ArrayList和Vector使用了数组实现,这两者的实现原理差不多。Vector是线程安全的,ArrayList不是线程安全的,LinkedList使用了双向链表实现。

2.1 ArrayList

2.1.1 基本结构

ArrayList实现了List接口,继承了AbstractList抽象类,底层是数组实现的,并且实现了自增扩容数组的大小。实现了RandomAccess意味着可以实现随机访问

public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable

 默认的容量是10,。存数据的是transient Object[] elementData;注意这里的Object数组不是基本类型

为什么使用transient修饰数组?

如果采⽤外部序列化法实现数组的序列化,会序列化整个数组.内部提供了两个私有⽅法 writeObject 以及 readObject 来⾃我完成序列化与反序列化,从⽽在序列化与反序列化数组时节省了空间和时间。

2.1.2 add方法

先确认数组长度,再添加元素

 尾插的时候在数组尾部增加元素,性能是非常好的,时间复杂度为0(1)

每次扩容都要按照1.5倍的大小进行扩容,科学计算,避免浪费更多的空间。

2.2 LinkedList

2.2.1 基本结构

由双向链表组成。每个链表中的元素都是一个Node节点对象,它包含了前指针和后继指针,还有鵆数据的item三部分组成

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

Node(Node<E> prev, E element, Node<E> next) {
    this.item = element;
    this.next = next;
    this.prev = prev;
    }
}

 2.2.2 add方法

尾插法:创建一个Node对象插入链表尾部时间复杂度为O(1)

随机插⼊: node(index) ⼆分思想判断从前向后遍历还是从后向前。时间复杂度O(n/2)

2.2.3 get方法

链表的随机查找效率很低的,因为需要遍历一半的链表O(n/2)
 

 3.Stack栈

栈和队列都是为了实现某种需求⼀种逻辑结构。都可以使⽤数组/链表实现。

栈:先⼊后出,⼊栈出栈时间复杂度都为O(1)

应用:

栈的运⽤⼗分之⼴。函数调⽤栈,操作数栈,浏览器中的后退/前进,成对问题可以使⽤栈解决

4.Queue队列

概念: 先进先出,⼊队出队时间复杂度都为O(1)

队列这种数据结构既可以⽤数组来实现,也可以⽤链表来实现

应⽤场景:

等待排队的场景,阻塞队列⽤作⽣产消费模型

5.1. LinkedList插⼊快? ArrayList, LinkedList 随机插⼊,头尾插⼊效率⽐较?

ArrayList 随机(头插)插入的效率O(n)

ArrayList 尾插的效率O(1)

ArrayList get获取数据的时间复杂度O(1)

LinkedList默认尾插  时间复杂度为O(1)

LinkedList随机插入  时间复杂度为O(n/2)

LinkedList 获取数据  时间复杂度为O(n/2)二分查找的效率,需要遍历一半的链表

2.Map

2.1Map继承结构

Map接⼝作为Java中哈希表的顶级接⼝和集合Collection接⼝⽆关系 

 

  •  HashTable是性能比较差的哈希表,所有方法都是用了Synchronozed描述
  • TreeMap可排序的Map,底层使用红黑树实现。排序场景下考虑使用
  • HashMap 存储K-V键值对结构,近似O(1)的时间复杂度快速通过Key取value。
  • LinkedHashMap继承⾃ HashMap+⾃身维护了双向链表实现。
     

 2.2JDK1.7版本

1.7的HashMap使用数组+链表的形式存储

Entry:每个节点都是一个Entry的实例,Entry包含了四个属性:key,value,hash,next

capacity:当前数组的容量,始终保持着2^n,可以扩容,扩容后数组大小为当前的两倍

loadFactor:负载因子,默认为0.75

threshold:扩容的阈值,等于capacity * loadFactor

2.3 JDK1.8

JDK1.8对HashMap进⾏了不少修改,最⼤的不同就是使⽤ 红⿊树 优化链表。所以由数组+链表+红⿊树组成。根据 Java7 HashMap 的介绍,我们知道,查找的时候,根据 hash 值我们能够快速定位到数组的具体下标,但是之后的话,需要顺着链表⼀个个⽐较下去才能找到我们需要的,时间复杂度取决于链表的⻓度,为 O(n)。 此时哈希表退化成了链表为了降低这部分的开销,在 Java8 中,当链表中的 元素超过了 8 且数组⻓度⼤于64个以后,会将链表转换为红⿊树 ,在这些位置进⾏查找的时候可以降低时间复杂度为 O(logN)

Java7 中使⽤ Entry 来代表每个 HashMap 中的数据节点, Java8 中使⽤ Node,基本没有区别,都是key, value, hash 和 next 这四个属性,不过, Node 只能⽤于链表的情况,红⿊树的情况需要使⽤TreeNode 

 3.Set

set是无序不重复。其实现是基于Map进⾏了⼀些封装,代码极少。

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值