Java编程思想笔记0x0a

容器深入研究

Collection的功能方法

方法 说明
boolean add(T) 添加元素,如果类型不为T则返回false。可选
boolean addAll(Collection<? extends T>) 添加所有元素,只要添加了元素就返回true。可选
void clear() 移除所有元素。可选
boolean contains(T) 如果容器包含该元素,则返回true
boolean containsAll(Collection<?>) 如果容器中包含所有元素,则返回true
boolean isEmpty() 容器中没有元素返回true
Iterator<T> iterator() 返回一个可以遍历容器所有元素的Iterator<T>
boolean remove(Object) 如果元素在容器中,则移除一个该元素的实例。如果发生了移除则返回true。可选
boolean removeAll(Collection<?>) 移除参数中所有的元素,如果发生了移除就返回true。可选
boolean retainAll(Collection<?>) 只保存参数中的元素,只要Collection发生了改变就返回true
int size() 返回容器中元素的数目
Object[] toArray() 返回包含容器中所有元素的数组
<T> T[] toArray(T[] a) 返回包含容器中所有元素的数组,数组类型与参数类型一致

可选操作

  • Collection方法中,一些方法是可选的,这意味着继承Collection时这些方法可以不进行覆盖。此时导出类对象调用该方法时会出现UnsupportedOperationExceptionCollection的可选方法实现如下:

    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }
    

    可见,如果导出类不实现可选方法,那么该方法会调用Collection中的实现,即抛出一个UnsupportedOperationException异常。

Set与存储顺序

Set

  • 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法一确保对象的唯一性。SetCollection有完全一样的接口。Set不保证维护元素的次序。

HashSet

  • 为快速查找而设计的Set,存入HashSet的元素必须定义hashCode()HashSet存储元素的顺序是按照底层哈希桶号从小到大排序,如果桶号相同就按照放入桶的先后顺序。

TreeSet

  • 保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。元素必须实现Comparable接口

LinkedHashSet

  • 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的顺序)。

SortedSet

  • 可以保证其中的元素处于排序状态,并提供一些附加功能

队列

LinkedList

  • 队列的基本实现。

优先级队列

  • PriorityQueue:按照元素从小到大排列。

Map

Map的各种实现

  • HashMapMap基于散列表的实现。插入和查询键值对的开销是固定的,可以通过构造器设置容量和负载因子,以调整容器性能

负载因子:如果容器持有元素超过一定比例会进行扩容,此时作为底层实现的旧数组会被更大容量的新数组取代。这个比例就是负载因子。

  • LinkedHashMap:类似于HashMap,但是迭代遍历时,取得键值对的顺序是插入顺序,或者是最近最少使用(LRU)次序。仅比HashMap慢一点,而在迭代访问时反而更快,因为其使用链表维护内部次序。
  • TreeMap:基于红黑树的实现。查看键或者键值对时,它们会被排序。TreeMap的特点在于,所得到的结果是经过排序的(按元素大小排序)。TreeMap是唯一带有subMap()方法的Map,它可以返回一棵子树。
  • WeakHashMap:弱键映射,允许释放映射所指向的对象,这是为解决某类特殊问题而设计的。如果映射之外没有引用指向某个键,则此键可以被垃圾回收。
  • ConcurrentHashMap:一种线程安全的Map,它不涉及同步加锁。
  • IdentityHashMap:使用==代替equals()对键进行比较的散列映射,专为解决特殊问题而设计的。

散列

  • HashMap使用了散列码作为键的搜索。在Java中,hashCode()是根类Object的方法,因此所有Java对象都能产生散列码。使用hashCode()进行查询能够显著地提高性能。
  • 默认的Object#equals()只是比较对象地址,如果需要某个自定义的类作为键使用,需要重载hashCode()equals()

容器的选择

List

  • ArrayList应该作为默认选择,只有当程序的性能因为经常从表中间进行插入和删除而变差的时候,才去选择LinkedList。如果使用的是固定数量的元素,也可以直接使用数组。

Set

  • HashSet的性能基本上总是比TreeSet好,特别是在添加和查询元素时。当需要对元素进行排序,或者需要对元素进行迭代时才会需要TreeSet

Map

  • 类似于Set的结果,TreeMapHashMap要慢。

实用方法

方法 说明
max(Collection), min(Collection) 返回参数Collection中最大或者最小的元素,采用Collection中内置的自然比较法
max(Collection, Comparator), min(Collection, Comparator) 返回参数Collection中最大或最小的元素,采用参数中的Comparator进行比较
indexOfSubList(List source, List target) 返回targetsource中第一次出现的位置,或者在找不到时返回-1
lastIndexOfSubList(List source, List target) 返回targetsource中最后一次出现的位置,或者在找不到时返回-1
replaceAll(List<T>, T oldVal, T newVal) 使用newVal替换所有oldVal
reverse(List) 逆转所有元素的次序
reverseOrder(), reverseOrder(Comparator<T>) 返回一个Comparator,它可以以逆转实现了Comparator<T>的对象集合的自然顺序。第二个版本可以逆转所提供的Comparator的顺序
rotate(List, int distance) 所有元素向后移动distance个位置,将末尾的元素循环到前面来
shuffle(List), shuffle(List, Random) 随机改变指定列表顺序。第一种形式提供其自己的随机机制,第二种则来源于参数Random对象
sort(List<T>), sort(List<T>, Comparator<? super T> c) 使用List<T>中的自然顺序排序。第二种形式允许提供用于排序的Comparator
copy(List<? super T> dest, List<? extends T> src) src中的元素复制到dest
swap(List, int i, int j) 交换list中位置i与位置j的元素,通常比手动实现要快
fill(LIst<? super T>, T x) 用对象x替换list中的所有元素
disjoint(Collection, Collection) 当两个集合没有重复元素时返回true
frequency(Collection, Object x) 返回Collectionx出现的次数
emptyList(), emptyMap(), emptySet() 返回不可变且为泛型的ListMapSet
singleton(T x), singletonList(T x), singletonMap(K key, V value) 产生不可变的Set<T>List<T>Map<K, V>
  • 在比较字符串而使用max()min()sort()等方法时,使用参数String.CASE_INSENSITIVE_ORDER可以忽略大小写。

同步控制

  • Collections.synchonizedCollection()可以传入一个新生成的容器,返回的是有同步功能的版本。类似的还有Collections.synchonizedList()Collections.synchonizedSet()Collections.synchonizedMap()等。
  • 快速报错:Java容器的一种保护机制,能够防止多个进程同时修改同一个容器的内容。它会探查容器上的任何除了当前进程进行的操作以外的所有变化,一旦发现其它进行修改了容器,就立刻抛出ConcurrentModificationException异常。
Author: SinLapis
Link: http://sinlapis.github.io/2019/07/07/Java编程思想笔记0x0a/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.