今日学习内容:
- IDEA
- 数组的拷贝
- 数组的冒泡排序
- 数组的二分查找
今日学习目标:
- 记住IDEA中的常用快捷键
- 熟练使用IDEA中的Debug调试
- 了解package关键字,能够使用IDEA工具创建包即可
- 了解数组的冒泡排序
- 了解数组的二分查找
- 会调用API中操作数组的常用方法,比如:arraycopy, sort,binarySearch,toString方法
- 了解import关键字
7. IDEA工具
7.1. IDEA的快捷键
参考《IDEA快捷键.md》文件中的快捷方式, 熟练使用红色字体标注的常用快捷方式。
7.2. Debug调试工具
参考《IDEA之Debug调试工具(常用版).pdf》
8. 数组拓展
8.1.数组拷贝(掌握)
需求:定义一个方法arraycopy, 从指定源数组中从指定的位置开始复制指定数量的元素到目标数组的指定位置。
拷贝前:
拷贝后:
代码如下:
public class ArrayCopyDemo {
public static void main(String[] args) {
int[] a = new int[] { 10, 20, 30, 40, 50, 60, 70 };
int[] b = new int[10];
System.out.println(java.util.Arrays.toString(b));;// 打印拷贝前的数组
ArrayCopyDemo.arraycopy(a, 2, b, 4, 3);
System.out.println(java.util.Arrays.toString(b));;// 打印拷贝后的数组
}
/*
参数列表:
src - 源数组
srcPos - 源数组中的开始索引位置
dest - 目标数组
destPos - 目标数据中的开始索引位置
length - 要复制元素的数量
*/
static void arraycopy(int[] src, int srcPos, int[] dest, int destPos, int length){
for (int index = 0; index < length; index++) {
dest[destPos + index] = src[srcPos + index];
}
}
}
输出结果:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 30, 40, 50, 0, 0, 0]
8.2. 排序操作(掌握原理)
需求:完成对int[] arr = new int[]{2,9,6,7,4,1}数组元素的升序排序操作.
8.2.1.冒泡排序原理(掌握原理)
对未排序的各元素从头到尾依次比较相邻两个元素的大小关系,如果前一个元素大于后一个元素则交换位置,经过第一轮比较后可以得到最大值,同理第二轮比较后出现第二大值等。
针对int[] arr = new int[]{ 2, 9, 6, 7, 4, 1 }数组元素做排序操作:
该数组有6个元素,只需要5轮比较。
第1轮比较:需要比较5次,比较完出现最大值。
第2轮比较:需要比较4次,比较完出现第二大值。
第3轮比较:需要比较3次,比较完出现第三大值。
...
可以看出如有N个元素,则需要N-1轮比较,第M轮需要N-M次比较。
交换数组中两个元素的方法
static void swap(int[] arr, int index1, int index2) {
int temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
排序代码:
package cn.wolfcode.array;
public class ArraySortDemo{
public static void main(String[] args) {
int[] arr = new int[] { 2, 9, 6, 7, 4, 1 };
System.out.println(Arrays.toString(arr));//排序前
ArraySortDemo.sort(arr);
System.out.println(Arrays.toString(arr));//排序后
}
static void sort(int[] arr) {
//第一轮:
for (int i = 1; i <= arr.length-1; i++) {
if (arr[i - 1] > arr[i]) {
ArraySortDemo.swap(arr, i - 1, i);
}
}
//第二轮:
for (int i = 1; i <= arr.length - 2; i++) {
if (arr[i - 1] > arr[i]) {
ArraySortDemo.swap(arr, i - 1, i);
}
}
//第三轮:
for (int i = 1; i <= arr.length - 3; i++) {
if (arr[i - 1] > arr[i]) {
ArraySortDemo.swap(arr, i - 1, i);
}
}
}
}
寻找规律,优化上述代码:
static void sort(int[] arr) {
for (int times = 1; times <= arr.length - 1; times++) {
//times表示第几轮比较,值为:1,2,3,4,5
for (int i = 1; i <= arr.length - times; i++) {
if (arr[i - 1] > arr[i]) {
App.swap(arr, i - 1, i);
}
}
}
}
8.3.二分法查找(掌握原理)
查找数组元素的算法:
- 线性查找:从头找到尾,性能比较低。
- 二分法查找(折半查找):前提数组元素是有序的,性能非常优异。
8.3.1.二分法搜索原理(掌握原理)
猜数字游戏:
电脑随机生成一个[ 1 , 100 ]之间的整数a,等玩家来猜,猜之后,电脑提示出三种结果:你猜的数偏大,偏小和猜中了。此时为了使用最少次数猜中,玩家必定先猜(1+100)/2的商50,如果此时电脑提示猜的偏小了,那就能推断出该随机数在[ 51 , 100 ]之间,此时再猜(51+100)/2的商75,如果电脑提示猜大了,那么该随机数必在[ 51 , 74 ]之间,那么继续猜(51+74)/2的商,如此每次都可以排除剩下结果一半的可能性,直到猜到为止。
代码如下:
package cn.wolfcode.array;
public class ArraySearchDemo{
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int index = ArraySearchDemo.binarySearch(arr, 8);
System.out.println(index);
}
static int binarySearch(int[] arr, int key) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
int midVal = arr[mid];
if (midVal < key) {
low = mid + 1;
} else if (midVal > key) {
high = mid - 1;
} else {
return mid;
}
}
return -1; // 没有找到
}
}
8.4.操作数组的API
类似打印数组元素的这样的工具性的方法,其实SUN公司的攻城狮们早就写好代码了,并封装在了很多工具类中,我们把这种预先定义好的方法,称为API。对于我们而言,最基本的要求就是能调用这些方法,当然我们对自己有更高的要求,应该知其然,并知其所以然。
学习API一定要掌握一个秘诀:文档在手, 天下我有!
工具类中的方法,一般都是使用static修饰的。
打开JDK帮助文档,搜索Arrays类,进入该类的文档页面,去找toString方法,发现在Arrays类中有多个toString方法,他们之间属于重载关系,分别用于打印不同类型的数组。
如: 查看Arrays类中将int类型数组转换成字符串的toString方法。
如果看方法列表看不懂怎么使用,使用鼠标左键点击该方法名称,进入该方法的详细:
如果看不懂,就要静下心来多看几次,必须掌握每一部分到底在表达什么意思。
8.4.1. 打印数组元素(掌握)
API中还有一个专门操作数组的工具类Arrays,该类提供了对数组元素的拷贝、元素搜索、元素排序、打印等功能方法,且该类为不同数据类型的数组都重载了相同功能的方法。
需求:通过调用Arrays类中的toString方法完成打印数组元素的功能,掌握如何给类定义包、导入类以及看API文档。
public class PrintArrayDemo {
public static void main(String[] args) {
int[] arr = new int[] { 10, 20, 30, 40, 50, 60, 70 };
String str = java.util.Arrays.toStirng(arr);
System.out.println(str);
}
}
8.4.2. 拷贝数组元素(会用)
System类中提供了数组元素拷贝的方法,并且支持任意类型的数组拷贝,而不仅仅是int类型数组。
public class ArrayCopyDemo {
public static void main(String[] args) {
int[] a = new int[] { 10, 20, 30, 40, 50, 60, 70 };
int[] b = new int[10];
System.out.println(java.util.Arrays.toString(b));// 打印拷贝前的数组
System.arraycopy(a, 2, b, 4, 3);
System.out.println(java.util.Arrays.toString(b));// 打印拷贝后的数组
}
}
8.4.3. 数组元素排序(会用)
Arrays类中已经提供了数组排序的方法sort,并且是调优之后的,性能非常优异,在开发中只需要我们直接调用该方法即可即可。
public class ArraySortDemo{
public static void main(String[] args) {
int[] arr = new int[] { 2, 9, 6, 7, 4, 1 };
System.out.println(Arrays.toString(arr));//排序前
java.util.Arrays.sort(arr);
System.out.println(Arrays.toString(arr));//排序后
}
}
8.4.4. 数组元素二分查找(会用)
Arrays类中已经提供了数组元素的二分查找。
public class ArraySearchDemo{
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int index = java.util.Arrays.binarySearch(arr, 8);
System.out.println(index);
}
}
小结:排序和二分法查找的原理需要掌握,当然, 在实际开发中, 会调用Arrays类中方法完成相关功能即可。
8.5.为类定义包-package(掌握)
在开发中存在几百个Java文件,为了更好的管理多个Java文件,我们可以使用package(包)来组织管理,类似于磁盘的文件夹一样,定义语法为:
语法格式:
package 包名.子包名.子子包;
如:
package test.demo;
注意:
- 必须把该语句作为Java文件中第一行代码(所有代码之前)
- 包名使用全小写字母组成,命名符合标识符规范
- 父包和子包之间使用点符号(.)分割
- 因为Java的安全机制,自定义包名不允许使用java单词作为包名。
企业中起名规范:
package 企业域名倒写.模块名.组件名;
如 package cn.wolfcode.array;
分包效果如下图:
创建出来的类,代码如下:
package cn.wolfcode.array;//当前类所在的包
public class ArrayCopyDemo {
public static void main(String[] args) {
}
}
类的名称:
- 简单名称:ArrayCopyDemo
- 全限定名:包名.简单名称,即cn.wolfcode.array.ArrayCopyDemo
8.6.组织导入类-import(掌握)
在代码中使用Arrays类中的toString方法打印数组:
public class PrintArrayDemo {
public static void main(String[] args) {
int[] arr = new int[] { 10, 20, 30, 40, 50, 60, 70 };
String str = java.util.Arrays.toStirng(arr);
System.out.println(str);
}
}
注意:
- Arrays类在java.util包中, 不在java.lang包中,使用时必须使用全限定名称——****java.util.Arrays****去调用方法
- 使用的类直接在java.lang包中: 直接使用简单名称调用方法
- 使用的类不在java.lang包中: 必须使用全限定名调用方法
每次使用Arrays类,都必须使用Arrays类的全限定名来调用方法,确实很累,所以此时就该import关键字出场了。
语法:
import 类的全限定名; 表示只导入一个类.
import 包名.子包名.*; 表示会引入该包下的所有在当前文件中使用到的类
使用import把非java.lang包中的类引入到该Java文件中,就可以直接使用简单名称来使用了。
package cn.wolfcode.array;//自己类所在的包
import java.util.Arrays;//引入其他包中的Arrays类
public class PrintArrayDemo {
public static void main(String[] args) {
int[] arr = new int[] { 10, 20, 30, 40, 50, 60, 70 };
//在上面引入Arrays类后, 这里就可以直接使用Arrays的简单名称来访问Arrays类了
String str = Arrays.toStirng(arr);
System.out.println(str);
}
}
在一个Java文件中可以使用多个import引入多个非java.lang包下的类。
idea可以自动优化导入包,但是有多个同名的类调用不同的包,必须自己手动Alt+Enter设置
小结:对package定义包和import导入某个类,会用就可以了,不深究。
学习优势:
1.包含java前后端从 0 ->1 全过程教学, 内容全面, 知识点不遗漏, 学完即可参加实际工作.
2.课程为目前项目开发常用的技术知识,向用人单位对标,学以致用。那些脱离实际,废弃不用的,太前沿的框架技术前期不建议学。
3.一起学习,打卡,一起交流,希望能营造一个和线下一样的学习环境。