专栏首页后端技术漫谈Java容器(List、Set、Map)知识点快速复习手册(下)

Java容器(List、Set、Map)知识点快速复习手册(下)

前言

本文快速回顾了Java中容器的知识点,用作面试复习,事半功倍。

上篇:容器概览,容器中用到的设计模式,List源码

中篇:Map源码

下篇:Set源码,容器总结

其它知识点复习手册

HashSet

http://wiki.jikexueyuan.com/project/java-collection/hashset.html

https://segmentfault.com/a/1190000014391402

关键词:

  • 默认容量16,扩容两倍,加载因子0.75
  • 允许元素为null
  • 实现Set接口
  • 不保证迭代顺序
  • 非同步
  • 初始容量非常影响迭代性能
  • 底层实际上是一个HashMap实例 > public HashSet() {map = new HashMap<>();}

如果添加的是在 HashSet 中不存在的,则返回 true;如果添加的元素已经存在,返回 false。

对于 HashSet 中保存的对象,请注意正确重写其 equals 和 hashCode 方法,以保证放入的对象的唯一性。

HashSet 和 HashMap 的区别

重要:

1. HashMap中使用键对象来计算hashcode值

2. HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false

在这里插入图片描述

TreeSet

关键词

  • 实现NavigableSet接口
  • 可以实现排序功能
  • 底层实际上是一个TreeMap实例
  • 非同步
  • 不允许为null

LinkedHashSet

关键词

  • 迭代是有序的
  • 允许为null
  • 底层实际上是一个HashMap+双向链表实例(其实就是LinkedHashMap)
  • 非同步
  • 性能比HashSet差一丢丢,因为要维护一个双向链表
  • 初始容量与迭代无关(与LinkedHashMap相同),因为LinkedHashSet迭代的是双向链表

总结Set

HashSet:

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

TreeSet:

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

LinkedHashSet:

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

WeekHashMap

存储结构

WeakHashMap 的 Entry 继承自 WeakReference,被 WeakReference 关联的对象在下一次垃圾回收时会被回收

WeakHashMap 主要用来实现缓存,通过使用 WeakHashMap 来引用缓存对象,由 JVM 对这部分缓存进行回收。

private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>

ConcurrentCache

Tomcat 中的 ConcurrentCache 使用了 WeakHashMap 来实现缓存功能。

ConcurrentCache 采取的是分代缓存:

  • 经常使用的对象放入 eden 中,eden 使用 ConcurrentHashMap 实现,不用担心会被回收(伊甸园);
  • 不常用的对象放入 longterm,longterm 使用 WeakHashMap 实现,这些老对象会被垃圾收集器回收。
  • 当调用 get() 方法时,会先从 eden 区获取,如果没有找到的话再到 longterm 获取,当从 longterm 获取到就把对象放入 eden 中,从而保证经常被访问的节点不容易被回收。
  • 当调用 put() 方法时,如果 eden 的大小超过了 size,那么就将 eden 中的所有对象都放入 longterm 中,利用虚拟机回收掉一部分不经常使用的对象。
public final class ConcurrentCache<K, V> {

    private final int size;

    private final Map<K, V> eden;

    private final Map<K, V> longterm;

    public ConcurrentCache(int size) {
        this.size = size;
        this.eden = new ConcurrentHashMap<>(size);
        this.longterm = new WeakHashMap<>(size);
    }

    public V get(K k) {
        V v = this.eden.get(k);
        if (v == null) {
            v = this.longterm.get(k);
            if (v != null)
                this.eden.put(k, v);
        }
        return v;
    }

    public void put(K k, V v) {
        if (this.eden.size() >= size) {
            this.longterm.putAll(this.eden);
            this.eden.clear();
        }
        this.eden.put(k, v);
    }
}

常见问题总结

Enumeration和Iterator接口的区别

Iterator替代了Enumeration,Enumeration是一个旧的迭代器了。

与Enumeration相比,Iterator更加安全,因为当一个集合正在被遍历的时候,它会阻止其它线程去修改集合。

区别有三点:

  • Iterator的方法名比Enumeration更科学
  • Iterator有fail-fast机制,比Enumeration更安全
  • Iterator能够删除元素,Enumeration并不能删除元素

ListIterator有什么特点

  • ListIterator继承了Iterator接口,它用于遍历List集合的元素。
  • ListIterator可以实现双向遍历,添加元素,设置元素

在这里插入图片描述

与Java集合框架相关的有哪些最好的实践

如果是单列的集合,我们考虑用Collection下的子接口ArrayList和Set。

如果是映射,我们就考虑使用Map

  • 是否需要同步:去找线程安全的集合类使用
  • 迭代时是否需要有序(插入顺序有序):去找Linked双向列表结构的
  • 是否需要排序(自然顺序或者手动排序):去找Tree红黑树类型的(JDK1.8)
  • 估算存放集合的数据量有多大,无论是List还是Map,它们实现动态增长,都是有性能消耗的。在初始集合的时候给出一个合理的容量会减少动态增长时的消耗
  • 使用泛型,避免在运行时出现ClassCastException
  • 尽可能使用Collections工具类,或者获取只读、同步或空的集合,而非编写自己的实现。它将会提供代码重用性,它有着更好的稳定性和可维护性

参考

  • https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Java%20%E5%AE%B9%E5%99%A8.md
  • 公众号:Java3y
  • Eckel B. Java 编程思想 [M]. 机械工业出版社, 2002.
  • Java Collection Framework
  • Iterator 模式
  • Java 8 系列之重新认识 HashMap
  • What is difference between HashMap and Hashtable in Java?
  • Java 集合之 HashMap
  • The principle of ConcurrentHashMap analysis
  • 探索 ConcurrentHashMap 高并发性的实现机制
  • HashMap 相关面试题及其解答
  • Java 集合细节(二):asList 的缺陷
  • Java Collection Framework – The LinkedList Class

关注我

本人目前为后台开发工程师,主要关注Python爬虫,后台开发等相关技术。

原创博客主要内容

  • 笔试面试复习知识点手册
  • Leetcode算法题解析(前150题)
  • 剑指offer算法题解析
  • Python爬虫相关实战
  • 后台开发相关实战

同步更新以下博客

Csdn

http://blog.csdn.net/qqxx6661

拥有专栏:Leetcode题解(Java/Python)、爬虫开发

知乎

https://www.zhihu.com/people/yang-zhen-dong-1/

拥有专栏:码农面试助攻手册

掘金

https://juejin.im/user/5b48015ce51d45191462ba55

简书

https://www.jianshu.com/u/b5f225ca2376

电商价格监控网站

本人长期维护的个人项目,完全免费,请大家多多支持。

实现功能

  • 京东商品监控:设置商品ID和预期价格,当商品价格【低于】设定的预期价格后自动发送邮件提醒用户。(一小时以内)
  • 京东品类商品监控:用户订阅特定品类后,该类降价幅度大于7折的【自营商品】会被选出并发送邮件提醒用户。
  • 品类商品浏览,商品历史价格曲线,商品历史最高最低价
  • 持续更新中…

网站地址

https://pricemonitor.online/

个人公众号:Rude3Knife

本文分享自微信公众号 - Rude3Knife(Rude3Knife),作者:甜瓜

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [菜鸟SpringCloud实战入门]第七章:客户端主动刷新机制 + 服务化和高可用改造

    欢迎来到菜鸟SpringCloud实战入门系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud。

    Rude3Knife的公众号
  • [Selenium+Chrome使用总结]加载Flash、禁用JS脚本、滚动页面至元素、缩放页面

    前几周做了个使用Selenium的项目,踩了好多好多好多的Selenium的坑,越来越感觉他作为一个第三方库,对于Chrome的操作实在是有局限。另外,推荐大家...

    Rude3Knife的公众号
  • 开源实战 | Canal生产环境常见问题总结与分析

    Canal是阿里巴巴开源的数据库Binlog日志解析框架,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。

    Rude3Knife的公众号
  • Android自定义processor实现bindView功能的实例

    在现阶段的Android开发中,注解越来越流行起来,比如ButterKnife,Retrofit,Dragger,EventBus等等都选择使用注解来配置。按照...

    砸漏
  • 用 ContourPlot3D 绘制多面体

    WolframChina
  • PHP数据结构(七) ——串与实现KMP算法

    PHP数据结构(七)——串与实现KMP算法 (原创内容,转载请注明来源,谢谢) 一、定义 串是0个或多个字符组成的有限序列,任意连续字符组成的子序列称为子串,...

    用户1327360
  • Java程序员实战机器学习——从聚类算法开始

    本文适合有编程经验的程序员,是一篇机器学习的”Hello world!”,没什么理论知识,在意理论准确性的人请绕道。

    不会飞的小鸟
  • 类和对象,以及 LeetCode 每日一题

    将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

    Carlos Ouyang
  • Leetcode 21 Merge Two Sorted Lists

    Merge two sorted linked lists and return it as a new list. The new list should b...

    triplebee
  • 中国平板电脑用户行为报告

    小伙伴们平时都是怎么使用平板电脑的?有没有被砸过脸呢?快来看一下腾讯2014中国平板电脑用户行为报告吧,看看有多少小伙伴和你是一样的: ? ? ? ?

    腾讯大讲堂

扫码关注云+社区

领取腾讯云代金券