集合补充



集合工具类在java.util下,此类仅由静态方法组合或返回集合。

它包含对集合进行操作的多态算法,“包装器”,返回由指定集合支持的新集合。

如果提供给它们的集合或类对象为null,则此类的方法都抛出一个NullPointerException


1. 工具类


1.1 排序

返回值 方法 解释
void reverse(List<?> list) 反转元素的顺序
void sort(List list) 排序
void sort(List list, Comparator<? super T> c) 根据比较器排序
void swap(List<?> list, int i, int j) 交换元素位置

1.2 查找和替换

针对的是Collection接口

返回值 方法 解释
int binarySearch(List list, Object key) 二分查找返回索引,前提是用sort排好序了
void copy(List dest, List src) 将所有元素从一个list复制到另一个list
void fill(List list, T obj) 填充
int frequency(Collection c, Object o) 指定元素出现的次数
int indexOfSubList(List source, List target) 返回第一次出现的位置

1.3 同步

返回值 方法 解释
List synchronizedList(List list) 返回同步集合
Set synchronizedSet(Set set) 返回同步集合
Map synchronizedMap(Map map) 返回同步集合

这里同步其实就是在每个方法里面加synchronized ,同一个对象锁(final Object mutex),用了装饰者模式,现在不推荐使用了,下面列举一个例子

static class SynchronizedCollection<E> implements Collection<E>, Serializable {

        final Collection<E> c;  // Backing Collection
        final Object mutex;     // Object on which to synchronize

    	//装饰器,获取被装饰对象
        SynchronizedCollection(Collection<E> c) {
            this.c = Objects.requireNonNull(c);
            mutex = this;
        }

    	//装饰功能,加了锁,调用子类方法
        public int size() {
            synchronized (mutex) {return c.size();}
        }
}

如果用到Iterator迭代器,需要自行加锁,因为这个上面没有加锁

synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext()) {
        //foo(i.next());
        System.out.println(i.next());
    }
}


2. JUC并发包

java.util.concurrent,下面试着随便说说ConcurrentHashMap

  • 1.7用Segment分段锁,1.8用部分锁,下面用1.8讲解

  • 采用数组+链表+红黑树的数据结构

  • synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,提高并发,不是锁整个表

  • 检索操作不用加锁,get方法是非阻塞的

  • key和value都不允许为null

  • 采用 锁头部 + CAS 实现

  • CAS无锁算法,使用volatile保证可见性,然后对比当前值与内存是否相等,相等才修改,多个线程对同一变量修改时,只有一个能成功

​ 网络图(侵删)



3. 数组转集合

返回值 方法名 解释
List Arrays.asList(T... a) 返回数组的List集合
  • 若传参是普通类型的数组,List会把整个数组放到第一个元素里
  • 返回指定数组的固定大小的List,而且不能改变结构,因为此处的List不是util下的,是Arrays下的,没有实现增删元素
  • 若要互转 List list= new ArrayList( Arrays.asList(array) )


4. 迭代

如果不是并发的集合,迭代的时候不允许修改结构,会有快速失败机制,这个机制尽可能抛出并发修改错误,但不保证成功



5.RandomAccess接口

public interface RandomAccess {
}

主要功能是标识具有随机访问功能,有什么作用?别急

先判断传入list是否支持是否是的RamdomAccess的子类

是则调用indexedBinarySearch()方法

否则调用iteratorBinarySearch()方法,iteratorBinarySearch是专门处理链表的



6.HashMap 与 HashSet计算Hash的区别

HashMap使用键(Key)计算Hashcode, HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性



7.HashSet如何检查重复

当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让加入操作成功



原文地址:https://www.cnblogs.com/Howlet/p/12205057.html