Java 容器

Java容器

容器

java容器,或者应该叫java集合框架更为贴切。Java集合框架提供了一套性能优良、使用方便的接口和类,它们
位于java.util包中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rDt1Xuq3-1609855908938)(D:\notes\JavaSE\容器.png)]

Collection 接口

集合作为容器应该具有的功能(增,删,改,查),
不一定全有。
集合的基本操作:增加,删除,判断,取出

序号方法名作用
1add(Object obj)添加,存储的是对象的引用
2size()容器中元素的实际个数
3remove(Object obj) clear() removeAll(Collection<?>c) retainAll(Collection<?>c)删除
4contains(Object obj) isEmpty()判断元素
5iterator()遍历元素

List接口

特点:有序,不唯一(可重复)

List特有方法

序号方法名作用
1(增)add(index,element) addAll(index,Collection) addAll(Collection)在指定索引的位置上插入元素 在指定的引的位置上插入整个集合的元素 在结束插入整个集合的元素
2(删)remove(index)根据索引删除指定的元素
3(改)set(index,element)使用element替换指定索引位置上的元素
4(查)get(index) subList(from,to) listIterator();获取元素

ArrayList

  • 底层数据结构是数组。线程不安全

  • 默认初始化容量为10,如果指定,那么初始化成对应容量。

  • ArrayList是基于动态数组实现的,在增删时候,需要数组的拷贝复制。(navite 方法由C/C++实现)

  • add方法:(1)检查是否需要扩容 ,(2)添加元素

  • 扩容,扩容到原来的1.5倍

  • 删除元素时不会减少容量,若希望减少容量则调用trimToSize()

  • 它不是线程安全的。它能存放null值。

LinkedList

  • 底层数据结构是双向链表。线程不安全
  • LinkedList实现了Deque接口,因此,我们可以操作LinkedList像操作队列和栈一样

Vector

Vector是jdk1.2的类了,比较老旧的一个集合类。

  • 底层数据结构是数组。线程安全(Vector是同步的),但是有性能损失
  • ArrayList在底层数组不够用时在原来的基础上扩展0.5倍,Vector是扩展1倍。

如果想要ArrayList实现同步,可以使用Collections的方法:**

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

ArrayList增删慢不是绝对的(在数量大的情况下):

  • 如果增加元素一直是使用add()(增加到末尾)的话,那是ArrayList要快
  • 一直删除末尾的元素也是ArrayList要快【不用复制移动位置】
  • 至于如果删除的是中间的位置的话,还是ArrayList要快

但一般来说:增删多还是用LinkedList

CopyOnWriteArrayList

CopyOnWriteArrayList是同步List的替代品

  • 在修改时,复制出一个新数组,修改的操作在新数组中完成,最后将新数组交由array变量指向。
  • 写加锁,读不加锁
  • 遍历Vector/SynchronizedList是需要自己手动加锁的。CopyOnWriteArrayList使用迭代器遍历时不需要显示加锁

Set接口

特点:元素不可重复

可以先了解Map,了解了Map就自然能弄懂Set。

HashSet

无序,允许为null,底层是HashMap(散列表+红黑树),非线程同步

TreeSet

有序,不允许为null,底层是TreeMap(红黑树),非线程同步

保证元素的排序方式

LinkedHashSet

迭代有序,允许为null,底层是HashMap+双向链表,非线程同步

Map接口

HashMap

  • JDK8中HashMap的底层是:数组+链表(散列表)+红黑树

  • 无序,允许为null,非同步

  • 初始容量(16)和装载因子(0.75)对HashMap影响挺大的,设置小了不好,设置大了也不好

    装载因子初始值大了,可以减少散列表再散列(扩容的次数),但同时会导致散列冲突的可能性变大(散列冲突也是耗性能的一个操作,要得操作链表(红黑树)

  • 扩容:原始容量 * 2,底层数组的容量一定为2的整数次幂

HashMap并不是直接拿key的哈希值来用的,它会将key的哈希值的高16位进行异或操作,使得我们将元素放入哈希表的时候增加了一定的随机性

还要值得注意的是:并不是桶上有8位元素的时候它就能变成红黑树,它得同时满足我们的散列表容量大于64才行的~

HashTable

  • 底层是: 数组 + 链表
  • 线程安全的,但性能比较低
  • 不允许key和value为null
  • 默认初始化容量11
  • 扩容 原始容量 * 2 + 1

Hashtable是个过时的集合类,不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换

TreeMap

  • 实现了NavigableMap接口,而NavigableMap接口继承着SortedMap接口,所以TreeMap是有序的!
  • 底层是红黑树,它方法的时间复杂度都不会太高:log(n)
  • 非同步的,想要同步可以使用Collections来进行封装

LinkedHashMap

  • 底层是散列表和双向链表

  • 允许为null,不同步

  • 插入的顺序是有序的(底层链表致使有序)

  • 装载因子和初始容量对LinkedHashMap影响是很大的~

  • 初始容量对遍历没有影响——因为它遍历的是LinkedHashMap内部维护的一个双向链表,而不是散列表(当然了,链表双向链表的元素都来源于散列表)

  • LinkedHashMap可以设置两种遍历顺序:

    访问顺序(access-ordered)

    插入顺序(insertion-ordered)

    默认是插入顺序的

ConcurrentHashMap

  • JDK1.8底层是散列表+红黑树

  • ConCurrentHashMap支持高并发的访问和更新,它是线程安全

  • 检索操作不用加锁,get方法是非阻塞的

  • key和value都不允许为null

  • Hashtable是将所有的方法进行同步,效率低下。而ConcurrentHashMap作为一个高并发的容器,它是通过部分锁定+CAS算法来进行实现线程安全的。CAS算法也可以认为是乐观锁的一种~

  • 在高并发环境下,统计数据(计算size…等等)其实是无意义的,因为在下一时刻size值就变化了。

  • get方法是非阻塞,无锁的。重写Node类,通过volatile修饰next来实现每次获取都是最新设置的值

Iterator接口

所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。
▪ Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
▪ Iterator接口定义了如下方法:

hasNext()  //判断是否有元素没有被遍历
next()         //返回游标当前位置的元素并将游标移动到下一个位置
remove()   //删除游标左面的元素,在执行完next之后该
操作只能执行一次  

Collection返回的是Iterator迭代器接口,而List中又有它自己对应的实现–>ListIterator接口

ListIterator可以往前遍历,添加元素,设置元素

Comparable接口

所有可以“排序”的类都实现了java.lang.Comparable 接口,Comparable接口中只有一个方法

public int compareTo(Object obj)//返回 0 表示 this == obj
//返回正数 表示 this > obj
//返回负数 表示 this < obj
Collections.sort(list,new MyComparator());

实现了Comparable 接口的类通过实现 comparaTo 方法从而确定该类对象的排序方式。

Collections 工具类

Collections和Collection不同,前者是集合的操作类,后者是集合接口

Collections提供的静态方法

addAll():批量添加
sort():排序
binarySearch():二分查找
fill():替换
shuffle():随机排序
reverse():逆序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值