一、异常
Java中的异常都继承自Throwable类,从Throwable派生出Error和Exception,Error一般是JVM抛出的错误,比如StackOverFlowError,OutOfMemoryError,这些错误是无法挽回的,只能结束当前Java进程的执行;
Exception异常是Java应用抛出的,分为编译时期可检测的异常(如IOException)和运行时期的异常(NullPointerException),编译时期可检测的异常必须要处理,否则编译器会报错误,而运行时期的异常RuntimeException不需要强制处理,Exception异常一般可以通过捕获处理以后,程序可以继续正常执行。
1、throws:
声明当前函数的异常,但却并不处理这个异常,而是把异常抛给该函数的调用方。
2、throw:
抛出异常。
3、try{…}catch…:
其中try是把可能出现异常的部分括起来,如果都正常,就将try中的代码正常运行,并跳过catch语句继续向下执行;如果try里面的代码运行时发生了异常,那么try中剩下的部分就不执行了,而是跳到catch语句继续向下执行。
4、catch:
捕获相应的类型异常对象,catch块可以出现多个,catch块运行完,代码直接向下运行。
5、常见异常及结构如图:
6、优先级队列
优先级队列是基于二叉堆原理的优先级队列,队列用动态数组实现。他是非阻塞、非线程安全的。
插入:
(1)如果当前元素个数达到数组长度,则扩容。如果数组长度小于64,直接扩容1倍,否则扩容0.5倍;
(2)增加元素个数;
(3)上浮操作,找到合适的位置插入。在上浮的时候,如果comparator存在则用它确定优先级,否则用自然顺序确定优先级。
删除:
(1)获取最后一个元素
(2)将待删除的位置i和最后一个元素做下沉操作
(3)如果没有执行下沉操作,那么表示待删除的位置i是叶节点,需要通过上浮调整二叉堆
(4)执行上浮操作
代码实现:
public class PriorityQueue<T extends Comparable<T>> {
private T[] queue;
private int index; // 记录有效元素的个数
public PriorityQueue(){
this.queue = (T[])new Comparable[10];
}
// 入优先级队列
public void push(T val){
if(full()){
this.queue = Arrays.copyOf(queue, queue.length*2);
}
if(index == 0){
queue[index] = val;
} else {
siftUp(index, val); // 新插入的元素,要进行堆的上浮操作
}
index++;
}
/**
* 堆的上浮函数
*/
private void siftUp(int i, T val) {
while(i > 0){
int j = (i-1)/2;
if(queue[j].compareTo(val) < 0){
queue[i] = queue[j];
i = j;
} else {
break;
}
}
queue[i] = val;
}
// 出优先级队列
public T pop(){
if(empty())
return null;
T oldval = queue[0];
--index;
if(index > 0){
siftDown(0, queue[index]); // 删除元素,进行堆的下沉操作
}
return oldval;
}
/**
* 堆的下沉函数
*/
private void siftDown(int i, T val) {
for(int j=2*i+1; j<index; j=j*2+1){
if(j+1 < index && queue[j+1].compareTo(queue[j]) > 0){
j++;
}
if(queue[j].compareTo(val) > 0){
queue[i] = queue[j];
i = j;
} else {
break;
}
}
queue[i] = val;
}
boolean full(){
return index == queue.length;
}
boolean empty(){
return index == 0;
}
public static void main(String[] args) {
PriorityQueue<Integer> que = new PriorityQueue<>();
Random rd = new Random();
for (int i = 0; i < 20; i++) {
que.push(rd.nextInt(100));
}
while(!que.empty()){
System.out.print(que.pop() + " ");
}
System.out.println();
}
其中上浮下沉的过程与上篇堆排序中过程类似,故不详细解释。