今日内容
零、 复习昨日
一、作业
二、引用类型[重要]
三、Arrays
四、数组拷贝
五、数组扩容
六、数组排序[面试|笔试]
零、 复习昨日
数组是用来存储多个数据.
内存是连续空间,有下标,下标从0开始,最大到长度-1
(下标就是位置,参考电影院的座位标号)取值: int a = arr[0];
赋值: arr[0] = 10;
数组创建后能否改变长度: 不能,固定长度
数组创建后能否存储不同类型的数据: 不能
数组动态创建的语法,以int数组为例:int[] arr = new int[3];
数组静态创建的语法,以int数组为例: int[] arr = new int[]{1,2,3,4};
int[] = {11,22,33};遍历是什么意思: 一个一个的取出数组中的元素
通过练习发现数组的特点:
- 存储的顺序和遍历的顺序是一样的
- 存储的数据能重复
一、作业
1.需求:定义一个方法,找出int数组中,最大值的索引下标[1,2,23,5,6,7,8]
public static int searchMaxIndex() {
int a[] = {1,2,23,5,6,7,8};
int max = a[0];
// 找到最大值
for (int i = 1; i < a.length; i++) {
if (max < a[i]) {
max = a[i];
}
}
// 通过最大数找到它的下标
for (int i = 0; i < a.length; i++) {
if (max == a[i]){
return i;
}
}
return -1;
}
第二种方案
public static int gmax() {
int[] arr = {1,2,23,5,6,7,8};
int max = arr[0];
int index = 0; // 假设最大数的下标是0
// 通过找到最大的数
for(int i = 1;i < arr.length;i++) {
if(arr[i] > max) {
max = arr[i];// 这是最大的数
index = i; // i就是最大数的下标
}
}
return index;
}
3.需求:定义一个方法,在指定的int数组中找出指定的数据第一个的下标,找到返回-1
[1,2,8,4,5,8,7,8,9]
// 主方法
public static void main(String[] args) {
int index = findIndexByElement(8);
System.out.println(index);
}
// 根据数据找下标
public static int findIndexByElement(int e) {
int[] arr = {1,2,8,4,5,8,7,8,9};
// 遍历
for (int i = 0; i < arr.length; i++) {
if (e == arr[i]) {
return i;
}
}
return -1;
}
4【难-变式】. 在一个数组中,找出所有的 指定数据的下标位置
[1,2,8,4,5,7,8,7,8,9]
/*
* 4【难】. 在一个数组中,找出所有的 指定数据的下标位置 并返回
[1,2,8,4,5,7,8,7,8,9]
-----------------
思路:
1. 将找到所有下标存储数组中返回(因为数组存储多个数据)
2. 找极端情况,假设数组全是重复数据,认为新数组和原数组一样长
*/
public static int[] findIndexByElement3(int e) {
// 原始数组
int[] arr = {1,2,8,4,5,8,7,8,9};
// 新数组,存下标
int[] indexArr = new int[arr.length];
// 假设下标从0开始放
int index = 0;
for (int i = 0; i < arr.length; i++) {
if (e == arr[i]) {
indexArr[index] = i;
index++;
}
}
// null就是数组的默认值
// return null;
return indexArr;
}
二、数组拷贝
数组拷贝: 将数组中的元素从一个数组赋值到另外一个数组中.例如:
int[] arr1 = {1,2,3,4};
int[] arr2 = new int[5];
// 将arr1里面数组元素赋值到arr2
方案一: 手动实现
// 数组拷贝
public static void copyArray() {
// 源数组
int[] arr1 = {11,22,33,44};
// 目标数组
int[] arr2 = new int[arr1.length];
// 拷贝前打印arr2
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i] + " ");
}
System.out.println("\r\n--------------");
// 遍历过程中完成拷贝
for (int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i];
}
// 拷贝完,打印arr2
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i] + " ");
}
}
利用拷贝,优化作业题4
/*
* 4【难】. 在一个数组中,找出所有的 指定数据的下标位置 并返回
[1,2,8,4,5,7,8,7,8,9]
-----------------
思路:
1. 将找到所有下标存储数组中返回(因为数组存储多个数据)
2. 找极端情况,假设数组全是重复数据,认为新数组和原数组一样长
3. 再创建一个和下标个数一样长的数组,使用数组拷贝
*/
public static int[] findIndexByElement3(int e) {
// 原始数组
int[] arr = {1,2,8,4,5,8,7,8,9};
// 临时数组,存下标
int[] tempArr = new int[arr.length];
// 假设下标从0开始放
int index = 0;
for (int i = 0; i < arr.length; i++) {
if (e == arr[i]) {
tempArr[index] = i;
index++;
}
}
// 创建最终存储下标数组
int[] indexArr = new int[index];
// 从临时数组中将下标拷贝到最终数组
for (int i = 0; i < indexArr.length; i++) {
indexArr[i] = tempArr[i];
}
// null就是数组的默认值
// return null;
return indexArr;
}
方案二: System类提供一个方法(了解)
// 重点!!!! 使用系统自带方法拷贝
/*
* src : 源(source)
* srcPos: 位置(position),从源数组哪里开始拷贝
* dest : 目的地(destination),目标数组
* destPos: 目标数组从哪开始放
* length: 长度,拷贝多少个
*/
System.arraycopy(arr1, 1, arr2, 1, 3);
// System自带拷贝的方法,直接使用即可完成
public static void copyArray2() {
// 源数组
int[] arr1 = {11,22,33,44};
// 目标数组
int[] arr2 = new int[2 * arr1.length];
// 拷贝前打印arr2
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i] + " ");
}
System.out.println("\r\n--------------");
// 重点!!!! 使用系统自带方法拷贝
/*
* src : 源(source)
* srcPos: 位置(position),从源数组哪里开始拷贝
* dest : 目的地(destination),目标数组
* destPos: 目标数组从哪开始放
* length: 长度,拷贝多少个
*/
System.arraycopy(arr1, 1, arr2, 1, 3);
// 拷贝完,打印arr2
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i] + " ");
}
}
方案三: 系统数组工具类完成拷贝(了解)
// 系统自带Arrays数组工具类,完成拷贝
// 参数1是源数组,参数2 是拷贝多少个(从开头开始)
// 将拷贝的元素放入一个新数组返回
int[] arr2 =Arrays.copyOf(arr1, 2);
三、数组扩容
数组本身不能扩容,所谓"扩容",
其实是重新创建一个全新数组,容量变大
,然后将老数组内的元素拷贝
到新数组,然后将数组的名字重新命名为之前的名字,使用时,我们"感觉"像是扩容了.
/*
* 数组拷贝
*/
public static void resize() {
// 源数组
int[] arr = {11,22,33,44};
System.out.println("数组的长度:" + arr.length);
// 将数组扩容为原来2倍
int[] arr2 = new int[2 * arr.length];
// 数组拷贝,将源数组内容拷贝到新数组
System.arraycopy(arr, 0, arr2, 0, arr.length);
// 引用重新赋值
arr = arr2;
System.out.println("数组的长度:" + arr.length);
}
// 练习: 向数组存放元素,一直存放没有大小限制 (其实就是后续学习集合中ArrayList的思想)
// 变式简单点: 现有有一个数组,可以存储4个元素,当存储容量不够时,可以扩容一次变成存储8个元素 (需要限制只能存储非0数据,即认为0是没有存储数据)
四、数组排序[面试|笔试]
int[] arr = {3,2,5,1,4}; ----> {1,2,3,4,5}
4.1 冒泡排序算法
以升序为例: 相邻两个比较大小,如果前一个比后一个大,两者换位
int[] arr = {6,5,4,3,2,1};
// 开始排序
// 外层循环控制比较的趟数
// -1 最后一趟不比较
for (int i = 0;i < arr.length - 1;i++) {
// 内层循环控制每趟比较几次
// -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;
}
}
}
4.2 选择排序算法
public static void sort() {
int[] arr = {5,6,4,3,2,1};
// 遍历看初始效果
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println("\r ---------------");
for (int i = 0; i < arr.length - 1; i++) {
int min = i;// 假设第一个最低
// 与后续每个人相比,找最低的那个人下标
for (int j = i + 1; j < arr.length; j++) {
if(arr[j] < arr[min]) {
min = j;
}
}
// 找到最低的那个人,与我换位置
if(min != i) {
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
五、引用类型[重要]
Java的数据类型分为两大类:
基本数据类型
引用类型: 数组,类,接口
何为引用类型?
通过一个变量引用内存中的对象.那么这个变量就是引用.
例如: int[] arr = new int[]{1,1,1};
以上代码会在堆内存中开启出一个空间,有地址值.将地址值赋值给变量arr
arr其实就是对象,也是引用
.因为arr引用了内存中的数组
,我们可以通过arr引用的地址找到数组,操作数组
基本类型: 值传递
public static void main(String[] args) {
int a = 1;
System.out.println("1 a = " + a);
// 将a变量的值1传递给方法change中的变量a
change(a);
System.out.println("1 a = " + a);
}
/*
* 基本类型的传递: 值传递
*/
public static void change(int a) {
System.out.println("2 a = " + a);
a = a * 10;
System.out.println("3 a = " + a);
}
引用类型传递: 引用传递
public static void main(String[] args) {
// 初始一个数组
int[] arr = new int[]{1,1,1};
// 第一次输出
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println("\r\n-----------");
// 将数组传递给方法
// 其实是将数组引用的地址传递给了方法
change2(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println("\r\n-----------");
}
/*
* 引用类型: 引用传递(地址传递)
*/
public static void change2(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println("\r\n-----------");
// 将每个元素扩大十倍
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 10;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println("\r\n-----------");
}
package com.qf.array;
/*
* 利用引用类型的引用传递
* 来完成一些效果
*/
public class Demo6 {
public static void main(String[] args) {
int[] arr = {5,4,3,2,1};
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] +" ");
}
// 将数组的地址传递给方法
sort(arr);
System.out.println();
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] +" ");
}
}
// 从小到大队数组排序
// sort方法arr参数就指向内存那个数组,完成排序
public static void sort(int[] arr) {
// 外层循环控制比较的趟数
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;
}
}
}
}
}
总结:
- 基本类型在方法传参数,变量赋值等时候是值传递
- 引用类型在方法传参,变量赋值等时候是引用传递
- 方法执行进栈,执行完出栈,方法内的变量会随着方法出栈而消失
- 凡是new都会在堆内存开辟空间,分配地址,创建对象
六、Arrays工具类[常用]
Java提供的工具类,操作数组的.内部有方法
- copyOf()
- sort()
- toString()
/*
* Arrays工具类
*/
public class Demo7 {
public static void main(String[] args) {
int[] arr = {5,4,3,2,1};
// Arrays.toString()
// 将数组中的元素以字符串返回
String s1 = Arrays.toString(arr);
System.out.println(s1);
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
//Arrays.sort(arr) 会将数组按升序排序
Arrays.sort(arr);
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
System.out.println(Arrays.toString(arr));
}
}
- toString()
/*
* Arrays工具类
*/
public class Demo7 {
public static void main(String[] args) {
int[] arr = {5,4,3,2,1};
// Arrays.toString()
// 将数组中的元素以字符串返回
String s1 = Arrays.toString(arr);
System.out.println(s1);
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
//Arrays.sort(arr) 会将数组按升序排序
Arrays.sort(arr);
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
System.out.println(Arrays.toString(arr));
}
}