冒泡排序
public class Test {
public static void main(String[] args) {
int[] arr = {45, 25, 35, 55, 15};
// 冒泡排序
// 外层循环控制比较的轮数
for (int i = 0; i < arr.length - 1; i++) {
// 内层循环控制每轮比较的次数
for (int j = 0; j < arr.length - 1 - i; j++) {
// 比较并交换
if (arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println("排序后的数组:"+ Arrays.toString(arr));
}
}
选择排序
public class Test {
public static void main(String[] args) {
int[] arr = {45, 25, 35, 55, 15};
// 选择排序
// 外层循环控制比较的轮数
for (int i = 0; i < arr.length - 1; i++) {
// 内层循环控制每轮比较的次数
for (int j = i + 1; j < arr.length; j++) {
// 比较并交换
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.println("排序后的数组:" + Arrays.toString(arr));
}
}
二分查找
public class Test {
public static void main(String[] args) {
int[] arr = {10, 14, 21, 38, 45, 47, 53, 81, 87, 99};
System.out.println(searchElement(arr, 53));// 6
System.out.println(searchElement(arr, 50));// -1
}
// 定义一个方法,实现二分查找
public static int searchElement(int[] arr, int num) {
// 1.定义一个left变量,记录最左边元素的索引,初始值为0
int left = 0;
// 2.定义一个right变量,记录最右边元素的索引,初始值为数组长度-1
int right = arr.length - 1;
// 3.使用while循环查找,查找条件:left<=right
while (left <= right) {
// 4.在循环中,计算中间索引
int middle = (left + right) / 2;
// 5.判断中间索引对应的元素与要查找的元素是否相等
if (arr[middle] == num) {
// 6.如果相等,就直接返回中间索引
return middle;
}else if(arr[middle] > num) {
// 6.如果中间索引对应的元素 大于 要查找的元素,说明要查找的元素在左边,忽略右侧数据
right = middle - 1;
}else if(arr[middle] < num) {
// 6.如果中间索引对应的元素 小于 要查找的元素,说明要查找的元素在右边,忽略左侧数据
left = middle + 1;
}
}
// 来到这里,说明没有找到,返回-1作为标识
return -1;
}
}
异常
异常的产生
-
在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。
-
throw用在方法内,来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
public class Test {
public static void main(String[] args) {
System.out.println("开始");
method1(10);
System.out.println("结束");
}
public static void method1(int num){
if (num == 10){
// 可能会产生异常---创建异常对象
// throw**用在方法内,来抛出一个异常对象**,将这个异常对象传递到调用者处,并**结束当前方法的执行**。
throw new ArithmeticException("数学运算异常");
}else{
System.out.println("num不等于10");
}
}
}
-
使用声明处理异常,处理完后,如果程序运行期间没有出现异常,程序可以继续往下执行
-
使用声明处理异常,处理完后,如果程序运行期间有出现异常,程序不可以继续往下执行
捕获处理异常try…catch
- 注意:
-
try中的代码如果发生了异常,try中发生异常位置之后的代码就不执行了
-
try,catch都不能单独使用
-
-
执行流程:
-
首先执行try中的代码:
-
如果try中的代码发生了异常,就会执行catch里面的代码,执行完catch里面的代码后,程序继续往下执行
-
如果try中的代码没有发生异常,就不会执行catch里面的代码,而是继续往下执行
-
try{
可能会出现异常的代码
}catch(异常的类型 变量名){
处理异常的代码或者打印异常的信息
}finally{
无论异常是否发生,都会执行这里的代码(正常情况,都会执行finally中的代码,一般用来释放资源)
}
执行步骤:
1.首先执行try中的代码,如果try中的代码出现了异常,那么就直接执行catch()里面的代码,执行完后会执行finally中的代码,然后程序继续往下执行
2.如果try中的代码没有出现异常,那么就不会执行catch()里面的代码,但是还是会执行finally中的代码,然后程序继续往下执行
-
try/catch/finally都不可以单独使用
-
运行时异常被抛出可以不处理(不捕获也不声明抛出),通过编译
-
在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收
-
方法重写时的异常处理:
-
父类的方法声明处理异常,子类覆盖(重写)父类方法时,只能声明相同的异常或该异常子集
-
父类的方法未抛出的异常,子类覆盖(重写)父类方法时,只能捕获处理异常,不能声明处理异常
-
并发与并行
-
并行:指两个或多个事件在同一时刻发生(同时执行)。
-
并发:指两个或多个事件在同一个时间段内发生(交替执行)。
线程与进程
-
线程是进程的可执行单元
-
一个进程可以有多条线程
-
每个线程执行都会有独立的内存空间
-
Java线程的调度方式: 抢占式
概述:
java.lang.Thread类代表**线程**,所有的线程对象都必须是Thread类或其子类的实例
每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码
Java使用线程执行体来代表这段程序流,在Tread线程中,使用run()方法代表线程执行体
构造方法
public Thread():创建一个新的线程对象,默认名称
public Thread(String name):创建一个指定名字的新的线程对象
public Thread(Runnable target):创建一个带有指定任务的线程对象,通过参数Runnable指定任务
public Thread(Runnable target,String name):创建一个带有指定任务的线程对象并指定线程名字
常用方法
public String getName():获取当前线程名称
public void start():导致此线程开始执行; Java虚拟机调用此线程的run方法
public void run():此线程要执行的任务在此处定义代码
public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停执行
public static Thread currentThread() :返回对当前正在执行的线程对象的引用
通过Thread类的api,可以指定创建线程有2种方式:
1.通过继承Thread类的方式
2.通过实现Runnable接口的方式
实现方式创建线程的优势
实现Runnable接口比继承Thread类所具有的优势:
-
适合多个相同的程序代码的线程去共享同一个资源(任务)。
-
可以避免java中的单继承的局限性。
-
增加程序的健壮性,实现解耦操作,任务代码可以被多个线程共享,任务代码和线程独立。
-
线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。