Java基础(六)——容器

容器

在这里插入图片描述

1 List

  • ArrayList:Object[]数组
  • Vector:Object[]数组
  • LinkedList:双向链表

1.1 ArrayList和Vector区别

  • ArrayList是List的主要实现类,Object[]数组,线程不安全
  • Vector是List的古老实现类,Object[]数组,线程安全

1.2 ArrayList和LinkedList区别

  • 两者都是线程不安全
  • ArrayList使用Object[]数组,LinkedList使用双向链表
  • ArrayList的数组结构利于随机查找,LinkedList的链表结构利于增加和删除
  • ArrayList的空间主要浪费在列表结尾预留的容量空间,LinkedList的空间主要浪费在存储前驱和后继

1.3 ArrayList

继承于AbstractList,实现了List、RandomAccess、Cloneable、Serializable接口

  • RandomAccess:用于标记该集合支持快速随机访问
  • Cloneable:意味着该集合能被克隆
  • Serializable:意味着该集合支持序列化

扩容机制

  • 初始化时是空数组,当插入第一个元素时数组容量变成10,minCapacity=Math.max(10, minCapacity)
  • 当插入新元素时,直到所需要的最小容量minCapacity大于数组容量时,会将数组扩容为原先的1.5倍
  • 如果newCapacity还是小于minCapacity,则将新容量设置为minCapacity
  • 如果newCapacity大于最大容量限制Integer.MAX_VALUE,则将新容量设置为Integer.MAX_VALUE-8

1.4 Arrays.copyOf

// 以正确顺序复制一份当前列表,size表示新列表的长度
Arrays.copyOf(oldArr, size);

1.5 Arrays.asList

将数组转换为集合,但是底层仍然是数组,无法使用集合的相关方法

当传入的是基本数据类型数组,则集合种只有一个元素,这个数组本身

// 正确转换方式
List list = new ArrayList<>(Arrays.asList("a", "b", "c"));
List myList = Arrays.stream(myArray).collect(Collectors.toList());
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());

2 Set

  • HashSet:底层是HashMap,线程不安全,可以存储null值
  • LinkedHashSet:HashSet的子类,底层是LinkedHashMap,能够按照添加顺序遍历
  • TreeSet:底层使用红黑树,能够排序

2.1 如何检查重复

  • 首先计算对象的hashCode,如果没有相同的元素,则插入
  • 如果存在相同的元素,则用equals方法对比两个元素

3 Map

  • HashMap:JDK1.7之前采用数组+链表的拉链法,JDK1.8以后当链表长度大于8时,将链表转换为红黑树(如果当前数组的长度小于64,则会先扩容数组,而不是转换红黑树)
  • LinkedHashMap:继承自HashMap,能够按照添加顺序遍历
  • HashTable:数组+链表,线程安全
  • TreeMap:底层使用红黑树,能够排序

3.1 HashMap和Hashtable区别

  • HashMap线程不安全,HashTable线程安全
  • HashTable基本已经被淘汰
  • HashMap可以存储null值,HashTable不允许存储null值
  • HashMap默认容量16,扩容机制采用2的幂次方,HashTable默认容量11,扩容机制采用2n+1

3.2 HashMap

3.2.1 JDK1.7以前

数据结构:采用数组+链表形式,通过拉链法防止哈希冲突

在这里插入图片描述

计算哈希方法:经过扰动函数处理得到hash值,通过**(n-1)&hash**判断当前元素存放位置

// 扰动函数
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).

    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}
3.2.2 JDK1.8以后

数据结构:采用数组+链表+红黑树形式,当链表长度大于8时,将链表转换为红黑树(如果当前数组的长度小于64,则会先扩容数组,而不是转换红黑树)

在这里插入图片描述

计算哈希方法:经过扰动函数处理得到hash值,通过**(n-1)&hash**判断当前元素存放位置

// 扰动函数
static final int hash(Object key) {
  int h;
  // key.hashCode():返回散列值也就是hashcode
  // ^ :按位异或
  // >>>:无符号右移,忽略符号位,空位都以0补齐
  return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

4 Collections

void sort(List list)  //按自然排序的升序排序
void sort(List list, Comparator c)  //定制排序,由Comparator控制排序逻辑
void reverse(List list)  //反转
void shuffle(List list)  //随机排序
void swap(List list, int i , int j)  //交换两个索引位置的元素
void rotate(List list, int distance)  //旋转。当distance为正数时,将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面

int binarySearch(List list, Object key)  //对List进行二分查找,返回索引,注意List必须是有序的
int max(Collection coll)  //根据元素的自然顺序,返回最大的元素
int max(Collection coll, Comparator c)  //根据定制排序,返回最大元素
void fill(List list, Object obj)  //用指定的元素代替指定list中的所有元素。
int frequency(Collection c, Object o)  //统计元素出现次数
int indexOfSubList(List list, List target)  //统计target在list中第一次出现的索引,找不到则返回-1
boolean replaceAll(List list, Object oldVal, Object newVal)  //用新元素替换旧元素

5 使用Iterator在遍历中删除元素

Iterator<String> iterator = list.listIterator();
while (iterator.hasNext()){
  iterator.remove();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值