数组
1.数组的概念
数组是在内存中开辟出的一块连续的、长度固定的,存放相同数据类型的存储空间。(连续、固定、相同)
2.数组的定义
方式1:
-----先声明、再分配空间-----
数据类型[] 数组名;
数组名 = new数据类型[长度];
方式2:
-----声明并分配空间-----
数据类型[] 数组名 = new 数据类型[长度];
方式3:
-----声明并赋值(繁)-----
数据类型[] 数组名 = new 数据类型[]{value1,value2,value3,…};
方式4:
-----声明并赋值(简)-----
数据类型[] 数组名 = {value1,value2,value3,…};
//显示初始化,注意:不可换行
package com.qfedu.test1;
public class Test4 {
public static void main(String[] args) {
// 方式1
// 先声明
int [] nums;
// 再分配空间
nums = new int[5];
// 方式2 声明 带 分配空间 一条语句完成
double [] ds = new double[5];
// 方式3 声明带赋值 长度依然是固定 根据元素的个数
String [] stra = new String[] {"a","b","c"};
// 方式4 声明带赋值 简写
char [] chars = {'a','b','c','d'};
}
}
3.数组的默认值
数组属于引用数据类型,其元素都有默认值(引用数据类型都有默认值)
整数:0 byte、short、int、long
小数:0.0 float 、double
字符:\u0000 char
布尔:false boolean
其他:null String等
package com.qfedu.test1;
/**
* 数组的默认值
* @author WHD
*
*/
public class Test3 {
public static void main(String[] args) {
byte [] bytes = new byte[5];
short [] shorts = new short[5];
int [] ints = new int[3];
long [] longs = new long[3];
for (int i = 0; i < longs.length; i++) {
System.out.println(longs[i]);
}
System.out.println("============================");
float [] fs = new float[3];
double [] ds = new double[6];
for (int i = 0; i < ds.length; i++) {
System.out.println(ds[i]);
}
System.out.println("============================");
char [] chars = new char[3];
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
boolean [] bs = new boolean[3];
System.out.println("============================");
for (int i = 0; i < bs.length; i++) {
System.out.println(bs[i]);
}
System.out.println("============================");
String [] strs = new String[5];
for (int i = 0; i < strs.length; i++) {
// 引用数据类型 默认值都是null
System.out.println(strs[i]);
}
}
}
4.数组的遍历
遍历:从头至尾,逐一对数组的每个元素进行访问。
属性:length,表示数组的长度,我们在遍历的时候可以借助length属性避免下标越界。
package com.qfedu.test1;
public class Test2 {
public static void main(String[] args) {
int [] nums = new int[5];
nums[0] = 66;
nums[1] = 77;
nums[2] = 88;
nums[3] = 99;
nums[4] = 22;
// 判断条件可以直接写值 但是有可能会写错 所以我们可以使用数组的属性 length 来作为判断条件
// 属性length表示数组的长度 是一个int类型的值
// 使用方式 数组名+.+length
System.out.println("nums数组的长度是" + nums.length);
for(int i = 0; i < nums.length ; i++) {
System.out.println(nums[i]);
}
}
}
5.数组在内存中的位置
6.复制数组
方式1:
创建一个新的数组,将原数组的内容一次存放到新数组中
方式2:(无返回值,需先创建好新数组)
System.arraycopy(src, srcPos, dest, destPos, length);
第一个参数 原数组名称
第二个参数 从原数组复制的起始位置 下标
第三个参数 新数组名称
第四个参数 从新数组的哪个位置开始复制
第五个参数 复制长度
方式3:(有返回值,会返回一个新数组)
Arrays.copyOf(original, newLength)
第一个参数 原数组名称
第二个参数 新数组长度
当前方法会返回给我们一个新的数组
package com.qfedu.test2;
public class Test3 {
public static void main(String[] args) {
// 数组扩容 方式1
int [] oldArr = new int[5];
oldArr[0] = 11;
oldArr[1] = 22;
oldArr[2] = 33;
oldArr[3] = 44;
oldArr[4] = 55;
int [] newArr = new int[oldArr.length * 2];
for(int i = 0 ; i < oldArr.length ;i++) {
newArr[i] = oldArr[i];
}
for (int i = 0; i < newArr.length; i++) {
System.out.println(newArr[i]);
}
// 方式2
// 第二种方式 System.ArrayCopy();
// 第一个参数 原数组名称
// 第二个参数 从原数组复制的起始位置 下标
// 第三个参数 新数组名称
// 第四个参数 从新数组的哪个位置开始复制
// 第五个参数 复制长度
int [] nums1 = new int[5];
nums1[0] = 11;
nums1[1] = 22;
nums1[2] = 33;
nums1[3] = 44;
nums1[4] = 55;
int [] nums2 = new int[10];
System.arraycopy(nums1, 0, nums2, 2, 3);
// 0 0 11 22 33 0 0 0 0 0
for (int i = 0; i < nums2.length; i++) {
System.out.print(nums2[i] + "\t");
}
// 第三种方式 Arrays.copyOf();
// 第一个参数 原数组名称
// 第二个参数 新数组长度
// 当前方法会返回给我们一个新的数组
int [] nums = {11,22,33,44,55};
int [] newNums = Arrays.copyOf(nums, 10);
for (int i = 0; i < newNums.length; i++) {
System.out.print(newNums[i] + "\t");
}
}
}
7.值传递和引用传递
值传递:当传入的参数是基本数据类型时,传入的是值的副本(值的拷贝),不会对原来的值产生改变
引用传递:当传入的参数是引用数据类型时,传入的是栈内存中保存的地址,等同于我们直接操作的是当前地址的内容,所以会改变原来的值。
String类型是特殊的引用数据类型(是不可变对象,被final修饰,后面会详讲),作为参数传入不会改变原有的值。
package com.qfedu.test3;
/**
* 值传递和引用传递的区别?
* 当我们传入的参数是引用数据类型传入的是地址,会改变原来的内容
* 当我们传入的参数是基本数据类型,传入的是值的拷贝,不会改变原来的内容
* @author WHD
*
*/
public class Test4 {
public static void main(String[] args) {
int [] nums = {11,22,33,44};
m1(nums);
System.out.println("引用数据类型,传递的是内存中的地址,会改变原来的变量");
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
System.out.println("值传递,传递的是值的副本,值的拷贝,不会使原来变量发生改变");
int num = 10;
m2(num);
System.out.println(num);
String str = "中国";
System.out.println("String类型是特殊的引用数据类型,不会改变原来的值");
m3(str);
System.out.println(str);
}
public static void m1(int [] nums) {
for (int i = 0; i < nums.length; i++) {
nums[i] += 1;
}
}
public static void m2(int num) {
num += 1;
}
public static void m3(String str) {
str += "abc";
}
}
8.数组类型的参数和数组类型返回值
package com.qfedu.test3;
public class Test2 {
public static void main(String[] args) {
// 现在有一个成绩数组 由于成绩算错了 所有的成绩都加一分
int [] scores = {78,87,86,89,98};
changeScore(scores);
for (int i = 0; i < scores.length; i++) {
System.out.print("修改之后的成绩" + scores[i] + "\t");
}
System.out.println();
int num = 20;
System.out.println("调用方法返回值是" + m1(num));
System.out.println("原来num的值" + num);
}
public static int[] changeScore(int [] scores) {
for (int i = 0; i < scores.length; i++) {
scores[i] += 1;
}
return scores;
}
public static int m1(int num) {
num += 10;
return num;
}
}
9.可变长参数
可变长参数要求:
- 形参列表中只能有一个
- 必须在形参列表的最后(如果在前,不知道形参列表会有多少个元素呀,后面的就没法传参啦)
package com.qfedu.test3;
public class Test5 {
public static void main(String[] args) {
// 可变长参数 要求形参列表只能有一个 并且必须在形参列表的最后
int [] nums = {11,22,33,44,55};
m1(20,nums);
System.out.println("======================");
m1(11,22,45,78,98,56,23);
m2(20,"a","b","c");
}
public static void m1( int a ,int ... args) {
for(int i = 0; i < args.length ; i++) {
System.out.println(args[i]);
}
}
public static void m2(int a,String ...strs) {
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
}
}
10.数组的排序
1.冒泡排序:
两两相比(两个相邻的数进行比较) 条件成立 互换位置
外层循环控制比较的轮数 轮数永远是 长度 -1 (n - 1)
内层循环控制每一轮比较的次数 最多的一次 长度-1 -i 并且是依次递减的 ( n -1 -i )
2.选择排序:
选择排序和冒泡排序 比较的次数是一样 n-1
唯独区别在与 冒泡是立即调换位置 而选择是当一轮比较完了以后 再调换位置
外层循环是比较是数A 内层循环是 比较的 数 B
3.JDK’自带的排序
Arrays.sort();方法
package com.qfedu.test4;
public class Test1 {
public static void main(String[] args) {
// 数组的排序 按照升序 或者 降序
// 快速 希尔 猴子 冒泡 选择 二叉树排序
// 冒泡排序 比较规则 两两相比(两个相邻的数进行比较) 条件成立 互换位置
int [] nums = {1,55,12,78,98,120,45};
// 外层循环控制比较的轮数 轮数永远是 长度 -1
// 内层循环控制每一轮比较的次数 最多的一次 长度-1 -i
for(int i = 0 ; i < nums.length -1 ; i++) {
for (int j = 0; j < nums.length -1 - i; j++) {
if(nums[j] < nums[j+1]) {
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + "\t");
}
// int a = 10;
// int b = 20;
// int temp = a;
// a = b;
// b = temp;
}
}
选择
package com.qfedu.test4;
public class Test2 {
public static void main(String[] args) {
// 选择排序和冒泡排序 比较的次数是一样
// 唯独区别在与 冒泡是立即调换位置 而选择是当一轮比较完了以后 再调换位置
// 外层循环是比较是数A 内层循环是 比较的 数 B
int [] nums = {1,55,12,78,98,120,45};
for (int i = 0; i < nums.length -1; i++) {
int minIndex = i; // 定义一个最小数的下标 假设从 i开始 依次与后边的数进行比较
for (int j = i + 1; j < nums.length; j++) {
if(nums[minIndex] > nums[j]) {
minIndex = j;
}
}
if(minIndex != i) {
int temp = nums[i];
nums[i] = nums[minIndex];
nums[minIndex] = temp;
}
}
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + "\t");
}
}
}
JDK自带排序
package com.qfedu.test4;
import java.util.Arrays;
public class Test3 {
public static void main(String[] args) {
int [] nums = {1,55,12,78,98,120,45};
// JDK自带的排序方法 只能升序
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + "\t");
}
// 将数组作为字符串输出
System.out.println(Arrays.toString(nums));
}
}
11.二维数组(了解)
概念:数组中的元素还是数组
定义方法:
方式1:
先声明、再分配空间:
数据类型[][] 数组名;
数组名 = new 数据类型[高维长度][低维长度];方式2:
声明并分配空间:
数据类型[][] 数组名 = new 数据类型[高维长度][低维长度];方式3:
声明并赋值(繁):
数据类型[][] 数组名 = new 数据类型[高维长度][]; //不规则数组,自行new低维数组方式4:
声明并赋值(简):
数据类型[] 数组名 = { {v1,v2,v3},{v4,v5},{v6,v7,v8,v9} }; //显示初始化
package com.qfedu.test4;
public class Test4 {
public static void main(String[] args) {
// 二维数组 数组中还是数组
// 二维数组在声明的时候 高维度的长度必须指定 也就是第一个中括号
int [][] nums = new int[3][];
nums[0] = new int[3];
nums[0][0] = 25;
nums[0][1] = 26;
nums[0][2] = 33;
nums[1] = new int[2];
nums[1][0] = 12;
nums[1][1] = 25;
nums[2] = new int[4];
nums[2][0] = 33;
nums[2][1] = 65;
nums[2][2] = 66;
nums[2][3] = 67;
System.out.println(nums[0].length);
System.out.println(nums[1].length);
System.out.println(nums[2].length);
System.out.println("=======================");
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[i].length; j++) {
System.out.print(nums[i][j] + "\t");
}
}
System.out.println();
int [][] nums1 = { {12,23,45} , {22,33,44}, {55,66,77}};
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums1[i].length; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
.length);
System.out.println(nums[1].length);
System.out.println(nums[2].length);
System.out.println("=======================");
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[i].length; j++) {
System.out.print(nums[i][j] + "\t");
}
}
System.out.println();
int [][] nums1 = { {12,23,45} , {22,33,44}, {55,66,77}};
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums1[i].length; j++) {
System.out.print("*");
}
System.out.println();
}
}
每日问题
1.用一句话描述数组(三个特点)
2.数组的长度是哪个属性
3.数组的下标从几开始
4.数组在内存中的位置,数组名字和数组中的值
5.创建数组的三种方式
6.求最大值的思路是什么,然后用代码实现
素材 int scores[]={89,56,45,78,12,3};
7.分别写明各个类型数组的默认值
8.数组长度为3,添加下标为3的元素可以吗?会发生什么
9.可变长参数如何使用,写法上有什么要求
10.值传递和引用传递的区别
11.Arrays类toString方法的作用
12.书写调试的步骤
13.你有对象吗?
解答
1.用一句话描述数组(三个特点)
连续 长度固定 数据类型相同
2.数组的长度是哪个属性
length
3.数组的下标从几开始
0
4.数组在内存中的位置,数组名字和数组中的值
名字 栈中
值 堆中
5.创建数组的三种方式
int [] nums;
nums[] = new int[2];
int [] nums1 = new int[3];
int [] nums2 = {11,22,33};
6.求最大值的思路是什么,然后用代码实现
素材 int scores[]={89,56,45,78,12,3};
先假设一个最大值,为数组中的其中一个元素,依次与其他元素比较,如果遇到比当前
元素还大的数,将较大的数赋值给当前元素
7.分别写明各个类型数组的默认值
0
0.0
null
false
\u0000
8.数组长度为3,添加下标为3的元素可以吗?会发生什么
不可以,下标越界
9.可变长参数如何使用,写法上有什么要求
数据类型…名字 ,在形参最后一个,只能有一个
10.值传递和引用传递的区别
值传递是值的拷贝,引用传递传递的是地址
11.Arrays类toString方法的作用
数组转换为字符串
12.书写调试的步骤
打断点,debug调试,step over (F6)
13.你有对象吗?