java中的集合

java中的集合分为value值(Collection)、key-value键值对(Map)两种。

存储值的有:List和Set

List有序可重复

  • 常用的有ArrayList和LinkedList
  • ArrayList底层使用的是数组
    特点是查询快增删慢(因为数组在内存中是一块连续的内存,如果插入删除可能需要大量移动内存)
    使用场景:用于查询使用较多,插入删除使用较少的情况
    缺点: 线程不安全,效率高
  • LinkedList底层使用的是链表
    特点是增删快查询慢(链表在内存中是不连续的,当前元素中存放有上一个和下一个元素的地址。查询时需要从头部开始,一个一个找,所以查询效率低;插入时不需要移动内存只需要改变指向)
    使用场景:用于查询使用较少,而插入删除使用较多的情况
    缺点: 线程不安全,效率高

Set无序不可重复(根据equals和hashcode判断)
一个对象要存储在set中,必须重写equals和hashcode方法
存储键值对的为Map

Connection接口:

List 有序,可重复

  • ArrayList
    优点: 底层数据结构是数组,查询快,增删慢。
    缺点: 线程不安全,效率高

  • Vector
    优点: 底层数据结构是数组,查询快,增删慢。
    缺点: 线程安全,效率低

  • LinkedList
    优点: 底层数据结构是链表,查询慢,增删快。
    缺点: 线程不安全,效率高

Set 无序,唯一

  • HashSet
    底层数据结构是哈希表。(无序,唯一)
    如何来保证元素唯一性?
    1.依赖两个方法:hashCode()和equals()
  • LinkedHashSet
    底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
    1.由链表保证元素有序
    2.由哈希表保证元素唯一
  • TreeSet
    底层数据结构是红黑树。(唯一,有序)
  1. 如何保证元素排序的呢?
    自然排序
    比较器排序
    2.如何保证元素唯一性的呢?
    根据比较的返回值是否是0来决定

针对Collection集合我们到底使用谁呢?(掌握)

唯一吗?

  • 是:Set

排序吗?

是:TreeSet或LinkedHashSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。

  • 否:List

要安全吗?

是:Vector
否:ArrayList或者LinkedList

查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。

如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。
如果你知道用集合,就用ArrayList。

map

Map接口有三个比较重要的实现类,分别是HashMap、TreeMap和HashTable。

  • TreeMap是有序的,HashMap和HashTable是无序的。
  • Hashtable的方法是同步的,HashMap的方法不是同步的。这是两者最主要的区别。

这就意味着:

  • Hashtable是线程安全的,HashMap不是线程安全的。
  • HashMap效率较高,Hashtable效率较低。 如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。
    查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有
    synchronized关键字,而HashMap的源码中则没有。
  • Hashtable不允许null值,HashMap允许null值(key和value都允许)
  • 父类不同:Hashtable的父类是Dictionary,HashMap的父类是AbstractMap

参考https://blog.csdn.net/zhangqunshuai/article/details/80660974

面试问题:说一下你对Map的理解

**思路:**先说一下map集合的特点,再说一下有哪些实现类,最后依次讲一下每个实现类特点

  1. Map主要用于存储键值对,根据键得到值,因此不允许键重复,但允许值重复。
  2. 在java中的一个接口java.util.Map,它有四个实现类,分别是HashMap、Hashtable、LinkedHashMap和TreeMap.
  3. 实现类
    hashmap是最常用的map,它根据键的hashcode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。
    (HashMap的本质可以认为是一个数组,数组的每个索引被称为桶,每个桶里放着一个单链表,一个节点连着一个节点。)

这里补充一下时间复杂度,hashmap查询分四步:

  1. 判断key根据key算出索引
    2.根据索引获得索引位置所对应的键值对链表
    3.遍历键值对链表,根据key找到对应的entry键值对
    4.拿到value
    分析:
    以上四步要保证HashMap的时间复杂度O(1),需要保证每一步都是O(1),现在看起来就第三步对链表的循环的时间复杂度影响最大,链表查找的时间复杂度为O(n),与链表长度有关。我们要保证那个链表长度为1,才可以说时间复杂度能满足O(1)。但这么说来只有那个hash算法尽量减少冲突,才能使链表长度尽可能短,理想状态为1。因此可以得出结论:HashMap的查找时间复杂度只有在最理想的情况下才会为O(1),而要保证这个理想状态不是我们开发者控制的

遍历的时候,取得的数据都是随机的。只允许最多有一条记录的键为Null;HashMap不是线程安全的,也就是说,多个线程同时写hashMap可能会导致数据不一致。

线程同步实现方法:
1、使用Collections.sychronizedMap方法 原理 同步代码块
2、使用ConcurrentHashMap 原理 切分成多个桶,每个桶都是一个线程安全的Hashtable,性能更高,推荐使用。

hashTable与hashMap类似,都继承自dictionary类,不同的是,它不允许空的键或值;但是支持线程同步,同步方式是方法上加锁sychronized,属于对象锁,一次只允许一个线程通过,所以写入速度会很慢。
linkedHashMap是HashMap的子类。所以它的特点是插入的时候会按照应用次数排序。遍历的时候得到的数据是先插入的。
TreeMap实现sortMap集合,把键按照升序排序。也可以指定比较器。使用iterator遍历时,得到的数据时排好序的。
参考https://blog.csdn.net/zgy956645239/article/details/105216680
https://www.cnblogs.com/123-shen/p/11603761.html
底层真的看不下去,以后再看吧
https://blog.csdn.net/visant/article/details/80045154hashmap

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值