泛型与容器

1、泛型

  • 好处:更好的安全性、更好的可读性
  • Java中因为类型参数会被替换为object,所以泛型中不能用基本数据类型Pair<int> minmax = new Pair<int>(1,100)不合法

2、列表和队列

  • 迭代的陷阱:在迭代的中间调用容器的删除方法
public void remove(ArrayList<Integer> list) {
    for (Integer a : list) {
        if (a <= 100) {
            list.remove(a) //抛出ConcurrentModificationException
            }
        }
    }
/**
迭代器内部会维护一些索引位置相关的数据,迭代过程中容器不能发生结构性变化(添加、插入、删除),否则索引位置就失效。
*/
  • ArrayList不是线程安全的,内部采用动态数组实现

1、可随机访问,按照索引访问效率高
2、除非数组已排序,否则按照内容查找元素效率低,性能与数组长度成正比
3、添加N个元素效率为O(N),N为数组长度
4、插入和删除元素效率低,因为需要移动元素,具体为O(N)

  • LinkedList内部是双向链表实现,每个元素在内存都是单独存放

1、按需分配空间
2、不可以随机访问,按照索引访问效率低
3、不管是否排序,按照内容查找元素效率都低
4、两端添加、删除元素效率高
5、中间插入、删除元素要先定位,效率较低,但修改本身效率很高

  • ArrayDeque实现了双端队列,内部使用循环数组实现

1、两端添加、删除效率很高
2、根据元素内容查找和删除的效率较低
3、没有索引位置的概念,不能根据索引进行操作

3、Map和Set

  • HashMap:实现Map接口,内部有一个哈希表即数组table,每个table[i]指向一个单向链表,根据键存取值,用键算出hash值,取模得到数组中的索引位置buketIndex,然后操作table[buketIndex]指向的单向链表

1、根据键存取值效率很高
2、键值对没有顺序,因为hash值是随机的
3、线程不安全

  • HashSet

    • set是没有重复元素,不保证顺序的容器接口
    • 与HashMap类似,HashSet要求元素重写hashCode和equals方法
    • 实现set接口,内部利用HasnMap实现:1、没有重复元素;2、高效添加、删除元素以及判断元素是否存在;3、没有顺序
  • 排序二叉树

    • TreeMap和TreeSet的实现基础
    • 顺序特点:左子树所有节点小于该节点,右子树所有节点大于gai
    • 基本的保存、删除、查找效率为O(h),h为树的高度
    • AVL树保证树的高度平衡,红黑树保证大致平衡
  • TreeMap

    • 按键而不是按值有序,它要么键实现Comparable接口,要么创建时传递一个Comparator对象
    • 内部是红黑树实现的
    • 根据键保存、查找、删除效率较高,O(h)
  • TreeSet

    • 实现了:排重和有序。排重是基于比较结果的
    • 基于TreeMap
    • 没有重复元素
    • 添加、删除元素,判断元素是否存在效率较高
    • 有序
    • 要求Comparable接口或者通过构造方法提供一个Comparator对象
  • LinkedHashMap

    • 是HashMap的子类,内部还有一个双向链表维护键值对的顺序
    • 插入顺序:先添加的在前面,后添加的在后面,修改操作不影响顺序
    • 访问顺序:最末尾的是最近访问的,最开始的是最久没被访问的,因为对一个键执行get/put操作后对应的键值对会移到链表末尾
    • 用于缓存

    1、缓存就是用来保存常用的数据,容量小访问快
    2、LRU是缓存里一种流行的替换算法,即当缓存满了,最近最少使用的先被清理出去

    • 内部维护一个单独的双向链表,默认是插入顺序
  • EnumSet:用位向量实现

    • 位向量就是用一个位表示一个元素的状态,一组位表示一个集合的状态,每个位对应一个元素,状态只有两种

4、堆与优先级队列

    • 是完全二叉树(给定任意一个节点可以根据其编号直接快速计算出其父节点和孩子节点编号)
    • 逻辑概念上是一颗完全二叉树,物理存储上使用数组,还有一定的顺序要求
    • 根据顺序分为:最大堆和最小堆
    • 最大堆:每个节点都不大于其父节点。最小堆相反
    • 添加和删除元素的时候有两个关键的过程以保持堆的性质,一个是向上调整一个是向下调整
  • PriorityQueue优先级队列

  • 队列长度没有限制,每个元素都有优先级,队头的元素优先级最高

  • 内部用堆实现,内部元素不是完全有序的,不过逐个出队会得到有序的输出

  • 查看头部元素效率很高,O(1),入队出队效率较高,O(log2(N))

  • 根据值查找和删除元素效率比较低,O(N)

  • 求中值:元素是动态添加(用一个最大堆一个最小堆)

步骤:
1、设当前中位数为m,最大堆维护<=m的元素,最小堆维护>=m的元素,但两个堆都不包含m
2、当新元素e到达与m进行比较,若e<=m将其加入最大堆,反之加入最小堆
3、第2步之后如果最大堆和最小堆元素个数差>=2,则将m加入元素个数少的堆中,然后从元素个数多的堆将根节点移除并赋值给m

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值