Java入门day 12 - 数组高级
1 IDEA
1.1 IDEA快捷键
快捷键 | 描述 |
---|---|
双击Shift | 查找任何内容,可搜索类、资源、配置项、方法等,还能搜索路径 |
Ctrl + N | 按类名搜索类,比如 Java,Groovy,Scala 等类文件 |
Ctrl + F12 | 查看当前类结构 |
Ctrl + H | 查看类的层次关系 |
Alt + F7 | 查找类或方法在哪被使用 |
Ctrl + X | 剪切行 |
CTRL + D | 拷贝当前行到下一行 |
Ctrl + Shift + U | 英文大小写切换 |
Alt + Enter | 最常用的快捷键,含包选择导入,帮助创建, 可以新建类、方法等任何东西等 |
Ctrl + Shift + Space | 智能补全 |
Ctrl + Alt + T | 选择并进行代码包围 |
Ctrl + 斜杠 | 单行注释 |
Ctrl + Shift + 斜杠 | 多行注释 |
Ctrl + Alt + L | 格式化代码 |
F2 | 定位到下一处的错误地方 |
Shift + F2 | 定位到上一处的错误地方 |
Ctrl + B或Ctrl+鼠标左键 | 跳转声明处 |
Ctrl + Alt + B | 跳转到实现处 |
Alt + J | 选中下一处当前选择的内容 |
Ctrl + Tab | 切换操作页面 |
Shift + F10 | 普通运行当前 |
Shift + F9 | Debug运行当前 |
1.2 IDEA Debug
- Debug 流程
- 在需要的观察的代码左边打个红色的断点
- 右键Debug, 进入Debug模式.
- F8( 下一步 ) , Ctrl+F2 ( 停止Debug ) , Alt+Shift+F7( 强制进入方法运行 ) , shift+F8( 退出方法 ) , F9( 进入下一个断点 ) , Alt+F9( 运行到光标所在的位置,前提是没有断点在前面拦着 )
2 数组拓展
2.1 数组拷贝
需求:定义一个方法arraycopy, 从指定源数组中从指定的位置开始复制指定数量的元素到目标数组的指定位置。
import java.util.Arrays;
//需求:定义一个方法,进行数组拷贝,并调用System中的数组拷贝方法
public class ArrayCopyDemo {
public static void main(String[] args) {
//静态定义一个原来的数组
int[] arr = {1, 2, 3, 4, 5, 6, 9, 7};
//动态定义一个拷贝后的数组
int[] newArr = new int[16];
int[] newArr1 = new int[16];
//调用自己写的方法
ArrayCopyDemo.arrayCopy(arr, 2, 3, newArr, 3);
//调用系统默认的方法
System.arraycopy(arr, 2, newArr1, 3, 3);
System.out.println("系统方法" + Arrays.toString(newArr1));
}
/*
* 原来的数组 arr
* 原来数组开始拷贝的索引位置 arrIndex
* 要拷贝的长数据长度 length
* 拷贝后的新数组 newArr
* 新数组开始存放数据的索引位置 newArrIndex
*/
public static void arrayCopy(int[] arr, int arrIndex, int length, int[] newArr, int newArrIndex) {
//循环遍历原来数组
for (int i = 0; i < length; i++) {
//把原来数组的索引加上拷贝开始的索引赋值给新数组原来索引也加上拷贝存放开始的索引
newArr[i + newArrIndex] = arr[i + arrIndex];
}
System.out.println("自己方法" + Arrays.toString(newArr));
}
}
2.2 冒泡排序
对未排序的各元素从头到尾依次比较相邻两个元素的大小关系,如果前一个元素大于后一个元素则交换位置,经过第一轮比较后可以得到最大值,同理第二轮比较后出现第二大值等。
import java.util.Arrays;
public class ArraySortDemo {
//定义一个sort方法,传入arr数组
public static void sort(int[] arr) {
//用第一层for循环表示第几轮的循环
for (int i = 0; i < arr.length; i++) {
//定义一个boolean类型的b用来提高效率
boolean b = false;
//用第二层for循环来操作交换,arr.length-1-i也是用来提高效率,写arr.length-1效率比较低
for (int j = 0; j < arr.length - 1 - i; j++) {
//如果前面一个数大于后面的数进行操作
if (arr[j] > arr[j + 1]) {
//定义一个temp来接收大的数
int temp = arr[j];
//把前面的数变成后面小的那个数
arr[j] = arr[j + 1];
//把后面的数变成大的那个数
arr[j + 1] = temp;
//如果有进行交换b就变成true
b = true;
}
}
//如果b=false,说明没有进入循环交换操作,那么!b等于true.执行if语句
if (!b) {
//跳出循环,结束
break;
}
}
}
public static void main(String[] args) {
int[] arr = {22, 3, 153, 123, 44, 13, 6, 0};
//使用到if(!b)提高效率
int[] arr1 = {1, 2, 3, 4, 44, 13, 99, 67};
int[] arr2 = {22, 3, 153, 123, 44, 13, 6, 0};
//调用自己的方法
ArraySortDemo.sort(arr);
System.out.println(Arrays.toString(arr));
//调用系统自带的方法
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
}
}
2.3 二分法查找
查找数组元素的算法:
- 线性查找:从头找到尾,性能比较低。
- 二分法查找(折半查找):前提数组元素是有序的,性能非常优异。
import java.util.Arrays;
public class ArraySearchDemo2 {
public static int binarySearch(int[] arr, int key) {
//先对数组进行排序
Arrays.sort(arr);
//定义数组最小索引
int low = 0;
//定义数组最大索引
int higher = arr.length - 1;
//因为不确定循环次数所以用while进行循环
while (low <= higher) {
//取到中间数的索引
int middle = (low + higher) / 2;
//拿到中间数索引的值
int middleValue = arr[middle];
//如果中间数索引的值大于我们要找的值
if (middleValue > key) {
//最大索引就变成中间索引-1
higher = middle - 1;
//如果中间数索引的值小于我们要找的值
} else if (middleValue < key) {
//最小索引就变成中间索引+1
low = middle + 1;
} else {
//如果中间索引的值等于我们要找的值,输出索引
return middle;
}
}
//如果找不到就输出-1
return -1;
}
public static void main(String[] args) {
int[] arr = {2, 1, 5, 8, 5, 4, 3, 44, 13};
int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8};
//调用自己的方法
int result = ArraySearchDemo2.binarySearch(arr, 44);
System.out.println(result);
//调用系统的方法
int result1 = Arrays.binarySearch(arr1, 5);
System.out.println(result1);
}
}
3.总结
3.1 数组元素拷贝的原理?
原数组从某个位置( 索引 )开始选定要拷贝的长度, 一个一个的把元素赋值到新数组的某个位置( 索引 )上.
3.2 数组元素冒泡排序的原理?
一步一步的比较相邻2个数的大小, 如果前面比后面大就交换2个数的位置, 一直进行下去, 直到没有数可以交换位置.
3.3 数组原素二分查找的原理?
当一个数组是有序排列的, 我们想要从中找到一个元素的位置, 我们可以先拿到数组的中间索引位置( 最小索引和最大索引的和 / 2), 拿中间数的值和我们想要的元素值进行比较, 如果比想要的元素值小, 那么最小索引就变成中间索引+1. 如果比想要的元素值大, 最大索引就变成中间-1. 一直重复直到找个改元素, 返回索引的位置, 或者当最小索引大于最大索引时, 说明该元素不存在, 结束程序.
3.4 什么是API?什么时候需要使用API?如何使用?
API: 是别人预先写好并封装在很多工具类中的方法.
什么时候需要使用API: 当我们需要的方法存在API中我们可以直接调用他们的方法, 减少我们所写的代码.
使用API: 1. import 类的全限定名; 表示只导入一个类 .
2. import 包名.子包名.*; 表示导入包下所有当前文件使用到的类.
3.5 包有什么作用? 包的定义的规范?
包的作用: 把java文件按照它的功能进行分类, 方便我们进行管理. 比如: 工具类都放在Util中.
包的定义规范: 1. Java文件的第一行代码必须是包名.
2. 包名使用企业域名的倒写, 由小写字母.
3. 子包和父包之间用.分隔.
4. 自定义包名不能用java来.
3.6 导包的作用是什么?
明确使用的方法来自哪个包的类中.