Java 基础 - 集合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 基础 - 集合相关的知识,希望对你有一定的参考价值。

Collection

技术分享            技术分享

Collection 集合

在 java.util 包中, 其中 Collection 包含:

  • List: 必须按特定的顺序容纳元素
  • Set: 不可包含任何重复的元素

注意: Map 不在 Collection 集合中.

Collection的主要方法

  • Boolean add(Object): 如果没添加, 则返回 false(Set 常用)
  • Boolean addAll(Collection)
  • void clear(): 清除所有
  • Boolean contains(Object): 包含(通过比较equals)则返回true
  • Boolean containsAll(Collection): 如果包含所有, 则返回true
  • Boolean isEmpty(): 没有元素返回true
  • Iterator iterator(): 返回迭代器,  Collection 唯一的迭代方法
  • Boolean remove(Object)true 代表有删除动作
  • Boolean removeAll(Collection)true 代表有删除动作
  • Boolean retainAll(Collection): 取交集, 有变动返回 true
  • int size()
  • Object[] toArray(): 返回一个数组
  • Object[] toArray(Object[] a)

1.8新特性

  • Spliterator<E> spliterator()
  • Stream<E> stream()
  • Stream<E> parallelStream()

List

List接口 继承自 Collection 接口, 它保证元素保存的顺序. 实现类主要有:

  1. ArrayList
  2. LinkedList

ArrayList

特点:

  • 用于替换 Vector
  • 数组实现
  • 提供随机访问
  • 查询快O(1), 插入删除慢

扩容:

  • 初始值: 0
  • 第一次增长: `minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
  • 之后是每次 3/2 * oldCapacity + 1: oldCapacity + (oldCapacity >> 1) + 1

LinkedList

特点:

  • 双向链表实现
  • 插入删除快
  • 随机查找慢, 时间复杂度为O(n)

Set

Set接口 继承自 Collection 接口, 它保证容器内元素唯一性, 不保证顺序. Set 中添加的对象, 必须重写了 equals() 方法(否则只是比较地址), 实现类有:

  1. HashSet
  2. TreeSet

HashSet

特点:

  • 需要 hashcode
  • 不保证顺序
  • 用 HashMap 实现, 每次add操作会调用 map.put(ele, 预定义假对象);

TreeSet

特点: 

  • 保证顺序
  • TreeMap 实现, 每次add操作会调用 map.put(ele, 预定义假对象);

Map

用于存储 "键值对".包含:

  1. HashMap
  2. TreeMap

HashMap

特点:

  1. 用于代替 Hashtable
  2. 需要重写 hashCode() 和 equals()
  3. 不保证顺序
  4. put() 和 get() 为常数时间

扩容:

  1. 初始值: 16, 负载因子为0.75, 初始阀值为 16*0.75
  2. 每次扩容, Capacity 加倍

Hashtable区别:

  1. 非线程安全, 要外部(调用者)保证线程安全
  2. 允许存放 <null, null>

影响HashMap性能的参数:

初始大小负载因子, 当(键值对数 > 总槽数 * 负载因子), 就会进行 rehash()

如何有效地减少rehash 操作, 以提高HashMap性能? 1. 在设置初始大小的时候, 要考虑实际要存储多少元素, 以及增长因子(什么时候扩容), 这样的话, 就可以减少 rehash 的次数. 2. 当有特别多元素要存储的时候, 初始值要考虑设置的大一点. 这比每次扩容改变大小效率高很多.

TreeMap

特点: 1. 在 红-黑 树的基础上实现. 2. key 不能为 null, 和 HashMap不同 3. 有 subMap() 方法, 可以返回树的一部分. 4. put() 和 get() 时间复杂度为 log(N) 5. 需要重写 equals() 6. 查询比 HashMap 快

TreeMap 是怎样排序的?

  1. 构造函数传入一个 Comparator接口的实现
  2. 存储的 Object 实现了 Comparable 接口

__Comparator 和 Comparable 有什么区别? Comparator是外部比较器, 其比较方法compare(T o1, T o2)有两个参数Comparable 是内部比较器, 起比较方法compareTo(T o) 只有一个参数

常用方法

排序和搜索

Array 排序

  1. 调用 Arrays.sort(a, new Comparator(){...})
  2. 假如 Object 实现了 Comparable 可以调用 Arrays.sort(a)

Array 搜索

  1. 先 sort
  2. 然后调用 Arrays.binarySearch()

List 排序

  • JDK 1.8 之前
    • 先转化成数组: Object[] a = list.toArray()
    • 调用 Arrays.sort(a, new Comparator(){...}), 假如 Object 实现了 Comparable 可以调用 Arrays.sort(a)
  • JDK 1.8 之后, 可调用 void sort(Comparator c) 方法
  • 调用 Collections.sort(List l)方法

List 搜索

Collections.binarySearch(List, Object)

Set

  • 转化成数组排序
    • 先转化成数组: Object[] a = list.toArray()
    • 调用 Arrays.sort(a, new Comparator(){...}), 假如 Object 实现了 Comparable 可以调用 Arrays.sort(a)
  • 将 HashSet 转化成 TreeSet

Map

  • 将 HashMap 转化成 TreeMap

其他实用方法

Collections

  1. enumeration(Collection)
  2. max(Collection)
  3. min(Collection)
  4. max(Collection, Comparator)
  5. min(Collection, Comparator)
  6. nCopies(int n, Object o): 返回一个不可边的List, 列表内的元素都指向 o
  7. unmodifiedbleCollection(Collection): 返回一个不可边的 Collection
  8. synchronizedList(List)
  9. synchronizedSet(Set)
  10. synchronizedMap(Map)

Enumeration和Iterator接口的区别?

Enumeration的速度是Iterator的两倍,也使用更少的内存。Enumeration是非常基础的,也满足了基础的需要。但是,与Enumeration相比,Iterator更加安全,因为当一个集合正在被遍历的时候,它会阻止其它线程去修改集合。

迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者从集合中移除元素,而Enumeration不能做到。为了使它的功能更加清晰,迭代器方法名已经经过改善。

其他容器

Array

优点: 可以容纳基本数据类型 缺点: 提前分配空间

Vector, Stack, Hashtable

Vector

特点: 

  • 实现了 List 接口
  • 线程安全, 方法都由 synchronized 标识, 有显著的性能开销
  • 内部用数组实现

扩容:

  • 初始值: 10 (默认构造函数)
  • 每次扩容: old + (capacityIncrement==0 ? 0 : oldCapacity) + 1

Stack

特点:

  • 继承自 Vector
  • 先入后出(LIFO)

扩容, 同 Vector

Hashtable

特点:

  • 实现了 Map 接口
  • 存储 key-value 对
  • 用内部类 Entry<K,V>(实现Map.Entry<K,V>接口) 数组 + 外部拉链法
  • 线程安全, 通过为方法上加 synchronized 保证

扩容:

  • 初始值: 11 (默认构造函数), 负载因子: 0.75
  • 扩容条件: 每次 rehash() 都会扩容
  • rehash 条件: count >= thresholdthreshold值为: 当前大小 * 负载因子
  • 每次扩容: newCapacity = (oldCapacity << 1) + 1
  • 最大不超过 MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8最大值-8)

默认的 hashcode 是多少?

hashcode默认值是由 Objecthashcode生成的, 值是这个对象的地址. 

为什么要存到 HashMap/HashList/Hashtable 中的对象要重写 equals 和 hashcode?

  1. hashcode 默认值是对象的地址, 假如一个对象在 Hashtable 中, 拿另外一个相等的对象查找, 会无法在 Hashtable 中检索到, 因为两个对象地址不同, 所以检索到的 enties[index] 不同.

  2. 之所以要重写 equals, 是因为虽然通过 hashcode 可以找到正确的 entries[index], 但是在链表中找相等元素, 是比较 equals 方法.

以上是关于Java 基础 - 集合的主要内容,如果未能解决你的问题,请参考以下文章

代码片段 - Golang 实现集合操作

laravel特殊功能代码片段集合

JSP基础

集合总结(全是代码)----------java基础学习

201621123062《java程序设计》第九周作业总结

Java方法