Java开发---类集(Collection)

Collection接口

Collection是单个集合保存的最大父接口

Collection接口定义
public interface Collection<E> extends Iterable<E>

Collection接口的重要方法

取得集合长度:int size();
判断集合是否为空:boolean isEmpty();
查找数据是否存在(需要使用equals()方法):boolean contains(Object o);
将集合变为数组对象返回: T[] toArray(T[] a);
向集合中添加数据:boolean add(E e);
删除数据(需要equals()方法):boolean remove(Object o);
清空数据void clear();
取得Iterator接口对象,用于集合输出:Iterator<E> iterator();

Collection接口的两个子接口

List接口(允许保存重复数据)

List接口的f两个扩充方法

  • 根据索引取得保存数据:public E get(int index);
  • 修改数据:public E set(int index,E element);

List接口的三个实现类

ArrayList:JDK1.2(运用最多)

  • 初始化策略:Lazy-load(懒加载策略),只有当Array对象第一次被使用(add)时,内部的数组才会初始化为长度为10的数
  • 扩容:每次扩容为原先数组的1.5倍
  • 线程安全性:线程不安全,但性能高
  • 输出形式:支持迭代输出,(foreach编译之后的class文件本身也为迭代输出);

Vector:JDK1.0

  • 初始化策略:当产生Vextor对象是,内部数组就初始化大小为10的数组
  • 扩容:每次扩容为原先数组的2倍
  • 线程安全性:使用synchronized同步方法来确保线程安全性,但性能低(读写互斥)
  • 输出形式:叠带输出。枚举输出

特殊:JDK内置的Stack继承Vector类

LinkedListJDK1.2

  • 基于双向链表的动态数组,线程不安全

特殊:JDK Queue的一个子类

ArrayList封装的是数组,LiinkedList封装的是链表,ArrayList时间复杂度为1,而LinkedList的复杂度为n

Set集合接口(不允许保存重复数据)

Set接口的常用子类

HashSet(无序存储)

底层实现:JDK1.8之前哈希表,1.8之后是哈希表和红黑树

HashSet使用equals与hashCode共同判断元素是否重复

  • hashCode:对象在内存中的地址根据Hash算法转为int
  • equals:判断两个对象属性是否相同

对象.equals与hashCode关系

  • equals相同,hashCode一定返回相同
  • hashCode相同,equals不一定相同

TreeSet(按照升序存储)

注意:不允许存放null

底层实现:红黑树
一个类要想使用TreeSet的两种方式

  • 自己实现了Comparable
  • 从外部传入一个该类的比较器对象(实现Comparator接口)

java.lang.Comparable : 内部排序接口
类实现了Comparable表示此类具备可比较的性质
int compareTo(T o);
> 0 : 大于目标对象
= 0 : 等于
< 0 : 小于目标对象

java.util.Comparator : 外部排序接口(最常使用) 策略模式
类本身不具备可比较的特性,专门有一个类来比较自定义类的大小
int compare(T o1, T o2);

TreeSet根据比较接口的返回值来判断两个元素是否重复

Collection的输出

迭代器输出

Iterator接口中的方法

  • 判断当前集合是否还有未遍历的元素:boolean hasNext();
  • 取得当前正在遍历的内容:E next();

取得该Collection接口对象的迭代器:Iterator<E> iterator();

输出格式(Scanner类也继承了Iterator接口)

while(iterator.hasNext()) {
	E e = iterator.next();
}

foreach:语法糖(只存在于代码编译阶段)

Collection接口能采用foreach输出的本质在于,所有子类都实现了Iterator接口

ListIterator(双向迭代输出-只有List接口有)

  • 判断当前集合是否还有上一个元素:boolean hasPrevious();
  • 取得上一个元素:E previous();

注意:要想从后向前输出:必须先从前到后输出一次

Enumeration(枚举输出-只有Vector及其子类Stack才有)

  • boolean hasMoreElements();
  • E nextElement();

快速失败策略(fail-fast)

优先考虑异常情况,当异常情况发生时,直接向用户抛出异常,程序终止。fail-fast保证集合在多线程场景下读到正确的值

// 取得集合迭代器时的modCount值
int expectedModCountexpectedModCount = modCount;
final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }

java.util.的集合类大多都采用此策略(ArrayList、Vector、LinkedList、HashSet,读写都在同一个副本中)

CopyOnWriteArrayList采用读写分离,所有的读为异步操作,写为同步操作,且读写不在一个副本

如何避免ConcurrentModificationException

  • 迭代输出的时候,不要修改集合的内容
  • 使用迭代器的修改方法

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值