1、集合
1.1 List:可重复
1、ArrayList:基于数组实现,增删慢,查询快,线程不安全
ArrayList是使用最广泛的List实现类,提供了对List的增加(add)、删除(remove)、访问(get)功能。
ArrayList不需要在定义时指定数组长度,在数组长度不能满足存储要求时,ArrayList会创建一个新的更大的数组并将数组中已有的数据复制到新的数组中。
2、LinkedList:基于双向链表实现,增删快,查询慢,线程不安全
LinkedList是一个双向链表,每一个节点都拥有指向前后节点的引用。
3、Vector:基于数组实现,增删慢,查询快,线程安全
Vector支持线程同步,即同一时刻只允许一个线程对Vector进行写操作,以保证多线程环境下数据的一致性,但需要频繁地对Vector实例进行加锁和释放锁的操作,因此,Vector的读写效率比整体上比ArrayList低。
1.2 Queue
Queue是队列结构。
- ArrayBlockingQueue:基于数组数据结构实现的有界阻塞队列
- LinkedBlockingQueue:基于链表数据结构实现的有界阻塞队列
- PriorityBlockingQueue:支持优先级排序的无界阻塞队列
- DelayQueue:支持延迟操作的无界阻塞队列
- SynchronousQueue:用于线程同步的阻塞队列
- LinkedTransferQueue:基于链表数据结构实现的无界阻塞队列
- LinkedBlockingDeque:基于链表数据结构实现的双向阻塞队列
1.3 Set:不可重复
Set适用于存储无序且值不相等的元素。对象的相等性在本质上是对象的HashCode值相同。
2、TreeSet:二叉树实现
TreeSet基于二叉树的原理对新添加的对象按照指定的顺序排序(升序、降序),添加的每一个对象都会进行排序,并将对象插入二叉树指定位置。
Integer和String等基础对象类型可以直接根据TreeSet的默认排序进行存储,而自定义的数据类型必须实现Comparable接口,并且覆盖其中的compareTo函数才可以按照预定义的顺序存储。
3、LinkHashSet:HashTable实现数据存储,双向链表记录顺序
LinkHashSet在底层使用LinkedHashMap存储元素,它继承了HashSet,所有的方法和操作都和HashSet相同。
1.4 Map
1、HashMap:数组+链表存储数据,线程不安全
HashMap基于键(key)的HashCode值唯一表示一条数据。同时基于键(key)的HashCode值进行数据存取。Has和Map的key和value允许为null。
HashMap是线程不安全的,在同一时刻有多个线程同时写HashMap时可能导致数据不一致。如果需要满足线程安全的条件,可以使用Collections的synchronizedMap方法,或使用ConcurrentHashMap。
HashMap的数据结构如图:
Entry实例包含4个属性:key、value、hash值和next指针。
HashMap查找数据的时间复杂度是O(N)。
Java8对HashMap进行了优化,将数据结构改为数组+链表或红黑树。在链表中的元素超过8个以后,HashMap会将链表结构转换为红黑树结构以提高查询效率,时间复杂度是O(logN)。
如图:
HashMap的常用参数包括:
- capacity:当前数组的容量,默认16,可以扩容,扩容后数组的大小为当前的两倍,因此该值始终为2n
- loadfactor:负载因子,默认0.75
- threshold:扩容阈值,其值等于capacity*loadfactor
2、ConcurrentHashMap:分段锁实现,线程安全
ConcurrentHashMap使用Segment(分段锁)技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问。所以说,ConcurrentHashMap在并发情况下,不仅保证了线程安全,而且提高了性能。(每个Segment均继承自ReemtrantLock)
ConcurrentHashMap的数据结构如图:
ConcurrentHashMap常用参数:
- concurrentLevel:并行级别,设置segment的个数,一旦初始化就不可以更改,默认16
Java8中ConcurrentHashMap中引入红黑树,具体数据结构如图:
3、HashTable:线程安全
Hashtable与HashMap类似,不同的是它继承自Dictionary类,并且线程安全,但并发性不如ConcurrentHashMap。
4、TreeMap:基于二叉树数据结构
TreeMap基于二叉树数据结构的存储数据,同时实现了SortedMap接口接口以保障元素的顺序存取,默认按键值升序排序。
5、LinkedHashMap
LinkedHashMap为HashMap的子类,其内部使用链表保存元素的插入顺序,遍历时按照元素插入顺序访问元素。
2、异常
方法在执行过程中出现异常时,Java异常处理机制会将代码的执行权交给异常处理器,异常处理器根据在系统中定义的异常处理规则执行不同的异常处理逻辑(抛出异常或捕捉并处理异常)。
2.1 异常分类
在Java中,Throwable是所有错误或异常的父类,Throwable又可分为Error和Exception,如图:
Error指Java程序运行错误。出现Error通常是因为系统的内部错误或资源耗尽,Error不能在运行过程中被动态处理。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。
Exception指Java程序运行异常,可以被Java异常处理机制处理。Exception可分为RuntimeException和CheckedException。
- RuntimeException:Java虚拟机正常运行期间抛出异常,RuntimeException可以被捕获并处理,如果出现RuntimeException,一定是程序发生错误导致的。常见的RuntimeException有NullPointerException、ClassCastException、ArrayIndexOutOfBoundsException、IllegalArgumentException等。
- CheckedException:在编译阶段Java编译器会检查CheckedException异常并强制程序捕获和处理此类异常,要求程序在可能出现异常的地方通过try catch语句块捕获并处理异常。常见的CheckedException有ClassNotFoundException、SQLException、IOException等。
2.2 异常处理方式
异常处理方式有抛出异常和使用try catch捕获异常。
(1)抛出异常:遇到异常是不进行具体处理,而是将异常抛给调用者,由调用者根据情况处理。抛出异常的方式有三种:throws、throw、系统自动抛出异常。
具体使用方法如下:
import java.io.*; public class className { //throws作用在方法上,用于定义方法可能抛出的异常 public void deposit(double amount) throws RemoteException { // Method implementation //throw作用在方法内,表示明确抛出一个异常 throw new RemoteException(); } //Remainder of class definition }
(2)使用try catch捕获异常并处理:使用try catch捕获异常能够针对性的处理每种可能出现的异常,并在捕获到异常后根据不同情况做不同的处理。
具体使用方法如下:
try{ //具体业务逻辑实现 }catch{ //捕获异常并处理 }
finally 关键字用来创建在 try 代码块后面执行的代码块。无论是否发生异常,finally 代码块中的代码总会被执行。
用法如下:
try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }finally{ // 程序代码 }