数组
文章目录
1. 数组的概念
在内存中一块
连续
的空间,用于存储相同
数据类型的值,长度是固定
的。
2. 数组的创建方式
先声明、再分配空间:
数据类型[] 数组名;
数组名 = new 数据类型[长度];
声明并分配空间:
数据类型[] 数组名 = new 数据类型[长度];
声明并赋值(繁):
数据类型[] 数组名 = new 数据类型[]{value1,value2,value3,…};
声明并赋值(简):
数据类型[] 数组名 = {value1,value2,value3,…};
public class Test {
public static void main(String[] args) {
// 方式1 先声明 再分配空间
int [] nums1;
nums1 = new int[5];
// 方式2 连声明 带分配空间
int [] nums2 = new int[3];
// 方式3 声明并且赋值 繁琐
int [] nums3 = new int[] {1,2,5,4,7,8};
// 方式4 声明并且赋值 简单
int [] nums4 = {55,88,77,44,22};
}
}
3. 数组的访问
数组中的每个数据称之为元素
访问数组中的元素通过下标,下标从0开始,依次+1
对数组中的元素赋值或者取值的操作称之为元素访问
访问方式 :数组名[下标]
不能访问超过下标范围的元素 会导致下标越界异常 ArrayIndexOutOfBoundsException
public class Test {
public static void main(String[] args) {
int nums1 [] = new int[5];
// 赋值
nums1[0] = 544;
nums1[1] = 220;
nums1[2] = 56;
nums1[3] = 10;
nums1[4] = 20;
// nums1[6] = 66; 不能访问超过下标范围的元素 会导致下标越界异常 ArrayIndexOutOfBoundsException
// 取值
System.out.println(nums1[0]);
System.out.println(nums1[1]);
System.out.println(nums1[2]);
System.out.println(nums1[3]);
System.out.println(nums1[4]);
}
}
4. 数组的遍历
遍历:逐一对数组的中的元素进行访问(取值/赋值),这个操作就称之为遍历
在我们使用循环访问数组的过程中,如果循环条件写错同样会导致数组下标越界异常
所以我们可以使用数组的属性 length 来实现循环访问数组
length是一个int类型整数数值 表示数组的长度
使用方法:数组名.length
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int [] arr1 = new int[4];
for(int i = 0;i < 4;i++) {
System.out.println("请输入第" + (i + 1) + "个元素的值");
arr1[i] = input.nextInt();
}
System.out.println("------------元素赋值完毕------------");
for(int i = 0;i < 4;i++) {
System.out.println("数组中的第" + (i + 1) + "个元素的值是:" + arr1[i]);
}
System.out.println("程序结束");
}
}
public class Test {
public static void main(String[] args) {
int [] arr = {1,5,8,7,4,57874,78,4,578,45,785,5,78,1,58,7,11,7,51,7};
System.out.println("数组的长度" + arr.length);
for(int i = 0;i < arr.length;i++) {
System.out.println(arr[i]);
}
}
}
5. 数组的默认值
数组作为引用数据类型,只要开辟完空间,那么数组中的元素是有默认值的
数组的默认值
整型:0
浮点:0.0
字符:\u0000
布尔:false
其他:null
public class Test {
public static void main(String[] args) {
byte [] b1 = new byte[3];
for (int i = 0; i < b1.length; i++) {
System.out.print(b1[i] + "\t");
}
System.out.println();
short [] s1 = new short[4];
for (int i = 0; i < s1.length; i++) {
System.out.print(s1[i] + "\t");
}
System.out.println();
int [] i1 = new int[5];
for (int i = 0; i < i1.length; i++) {
System.out.print(i1[i] + "\t");
}
System.out.println();
long [] l1 = new long[6];
for (int i = 0; i < l1.length; i++) {
System.out.print(l1[i] + "\t");
}
System.out.println();
float [] f1 = new float[3];
for (int i = 0; i < f1.length; i++) {
System.out.print(f1[i] + "\t");
}
System.out.println();
double [] d1 = new double[6];
for (int i = 0; i < d1.length; i++) {
System.out.print(d1[i] + "\t");
}
System.out.println();
char [] ch1 = new char[5];
for (int i = 0; i < ch1.length; i++) {
System.out.print(ch1[i] + "-" + "\t");
}
System.out.println();
boolean [] bl1 = new boolean[8];
for (int i = 0; i < bl1.length; i++) {
System.out.print(bl1[i] + "\t");
}
System.out.println();
String [] strs = new String[6];
for (int i = 0; i < strs.length; i++) {
System.out.print(strs[i] + "\t");
}
System.out.println();
}
}
6. 数组的扩容
数组作为引用数据类型,其引用(数组名)中保存的是指向堆中的地址。
数组扩容的步骤:
1.先创建一个更长的数组
2.将原数组中的元素依次赋值到新数组中
3.将原数组的地址改变为指向新的数组(这样即表示原数组的长度增加了)
/**
* 数组的扩容
*/
public class Test {
public static void main(String[] args) {
int [] oldArr = {1,2,3,4,5};
int [] newArr = new int[oldArr.length * 2];
for(int i = 0;i < oldArr.length;i++) {
newArr[i] = oldArr[i];
}
System.out.println("-----------------元素复制完毕-----------------");
for (int i = 0; i < newArr.length; i++) {
System.out.print(newArr[i] + "\t");
}
System.out.println();
// 最后一步 将新的数组赋值给老的数组
// 引用数据类型 赋值的是地址
System.out.println("赋值地址之前老数组的地址:" + oldArr);
System.out.println("赋值地址之前新数组的地址:" + newArr);
oldArr = newArr;
System.out.println("赋值地址之后老数组的地址:" + oldArr);
System.out.println("赋值地址之后新数组的地址:" + newArr);
for (int i = 0; i < oldArr.length; i++) {
System.out.print(oldArr[i] + "\t");
}
System.out.println();
}
}
7. 值传递和引用传递的区别?
Java官方明确指出没有引用传递,都属于值传递
面试题:值传递和引用传递区别?
基本数据类型都属于值传递,传递的是值本身(值的副本),在方法中对值的操作不会影响实参
引用数据类型都属于引用传递,传递的是地址,在方法中对引用数据类型的操作会影响实参
String类型是特殊的引用数据类型,作为参数传递不会影响实参
public class Test {
public static void m3(String str) {
str += "hello";
}
public static void m1(int num) {
num += 10;
System.out.println(num);
}
public static void m2(int [] arr) {
System.out.println("m2方法中arr的地址值:" + arr);
for (int i = 0; i < arr.length; i++) {
arr[i]++;
}
}
public static void main(String[] args) {
String str = "abc";
m3(str);
System.out.println(str);
int num = 10;
m1(num);
System.out.println(num); // 10
System.out.println("===================================");
int [] arr = {1,2,3,4,5};
System.out.println(arr);
m2(arr);
for(int i = 0;i < arr.length;i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
}
8. 数组练习
求数组元素的总和 以及 平均值
public class Test {
public static void main(String[] args) {
int [] nums = {11,22,33,44,55};
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
System.out.println("数组元素之和是:" + sum + "平均值是:" + sum / nums.length);
}
}
求数组中的最大值或者最小值
/**
* 求数组中的最大值或者最小值
*/
public class Test {
public static void main(String[] args) {
int [] nums = {11,578,5,63,987,15211,5588,9963};
// 1.假设数组中第一个元素为最大元素
int min = nums[0];
// 2.将假设最大值依次与后续元素进行比较
for(int i = 0;i < nums.length;i++) {
if(min > nums[i]) { // 3.如果遇到条件成立
min = nums[i]; // 4.交换"头衔"
}
}
System.out.println("数组中的最小元素是:" + min);
}
}
9. 复制数组的方式
1.编写循环实现复制
2.System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);
3.java.util.Arrays.copyOf(原数组, 新长度);//返回带有原值的新数组。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int [] nums1 = {1,2,3,4,5,6};
int [] nums2 = new int[10];
System.arraycopy(nums1, 1, nums2, 2, 2);
for (int i = 0; i < nums2.length; i++) {
System.out.print(nums2[i] + "\t");
}
System.out.println();
System.out.println("------------------------------------");
int [] nums3 = {1,2,3,4};
int [] nums4 = Arrays.copyOf(nums3, 3);
for (int i = 0; i < nums4.length; i++) {
System.out.print(nums4[i] + "\t");
}
System.out.println();
}
}
10. 数组参数/返回值/可变长参数
10.1 数组类型参数
数组类型参数与之前使用方式一致
形参和实参的规则继续保持
/**
* 数组类型的参数
* 编写方法将数组中的元素内容进行打印
*/
public class Test {
public static void main(String[] args) {
int [] nums = {1,2,5,8,9};
printArray(nums);
}
public static void printArray(int [] nums) {
for(int i = 0 ;i < nums.length;i++) {
System.out.print(nums[i] + "\t");
}
System.out.println();
}
}
10.2 数组类型返回值
Arrays.toString() 将数组中的元素转换为字符串 返回值为String类型
import java.util.Arrays;
import java.util.Scanner;
/**
* 数组类型的返回值
* 需求:编写方法提示用户输入5门成绩 作为返回值返回
*/
public class Test {
public static double[] inputScore() {
Scanner input = new Scanner(System.in);
double [] score = new double[5];
for (int i = 0; i < score.length; i++) {
System.out.println("请输入第"+ ( i + 1 )+"门成绩");
score[i] = input.nextDouble();
}
return score;
}
public static void main(String[] args) {
double [] scores = inputScore();
// Arrays.toString() 将数组中的元素转换为字符串 返回值为String类型
System.out.println(Arrays.toString(scores));;
for (int i = 0; i < scores.length; i++) {
System.out.print(scores[i] + "\t");
}
}
}
10.3 可变长参数
可变长参数
1.可以接收0个或者多个同类型的实参
2.必须在形参列表的末尾,并且整个形参列表中只能存在一个
语法:类型… 名称
本质上还是数组
public class Test {
public static void print(int... nums) {
for(int i = 0;i < nums.length;i++) {
System.out.print(nums[i] + "\t");
}
System.out.println();
System.out.println("print方法结束");
}
public static void main(String[] args) {
print(1,2,4,5,8,88,99,77,44);
}
}
11. 排序
1.1 冒泡排序
冒泡排序:两个相邻的元素进行比较,如果条件成立则交换位置
外层循环控制比较的轮数 数组长度-1
内层循环控制每一轮比较的次数 最多的一次是长度-1 后续递减1
外层循环 N - 1
内层循环 N - 1 - i
/**
* 排序算法:冒泡 选择 归并 希尔 桶排序 快速 猴子 …… 二叉树
*
* 冒泡排序:两个相邻的元素进行比较,如果条件成立则交换位置
*
* 外层循环控制比较的轮数 数组长度-1
* 内层循环控制每一轮比较的次数 最多的一次是长度-1 后续递减1
*
* 外层循环 N - 1
* 内层循环 N - 1 - i
*/
public class Test {
public static void main(String[] args) {
int [] nums = {1245,88,6963,7,25563,88,5,9633};
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;
}
}
System.out.println("第" + (i + 1) + "轮比较以后的顺序" + Arrays.toString(nums));
}
System.out.println(Arrays.toString(nums));
}
}
1.2 选择排序
选择排序:使用其中一个元素依次与其他元素比较 如果需要交换位置 先不交换
等待一轮比较完成 只交换一次位置
/**
* 选择排序:使用其中一个元素依次与其他元素比较 如果需要交换位置 先不交换
* 等待一轮比较完成 只交换依次位置
*/
public class Test {
public static void main(String[] args) {
int [] nums = {45,2,78,10,20,36547,852,96};
for(int i = 0;i < nums.length - 1;i++) {
int index = i;
for(int j = i + 1;j < nums.length;j ++) {
if(nums[index] < nums[j] ) {
index = j;
}
}
if(index != i) {
int temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
}
System.out.println("第"+(i + 1)+"轮比较完成以后" + Arrays.toString(nums));
}
System.out.println(Arrays.toString(nums));
}
}
1.3 JDK提供快速排序
JDK提供的快速排序(升序)
我们可以倒序插入到新的数组中,实现降序
/**
* JDK提供的快速排序(升序)
*/
public class Test {
public static void main(String[] args) {
int [] oldArray = {45,2,78,10,20,36547,852,96};
Arrays.sort(oldArray);
System.out.println(Arrays.toString(oldArray));
int [] newArray = new int[oldArray.length];
for(int i =0,j = oldArray.length -1;i < oldArray.length;i++,j--) {
newArray[j] = oldArray[i];
}
System.out.println(Arrays.toString(newArray));
}
}
12. 二维数组
二维数组:数组中的元素还是数组
定义二维数组,高维度长度必须写,低维度长度可以在赋值之前单独指定
二维数组的定义方式:与一维数组相同 依然有四种方式
/**
* 二维数组的定义方式:与一维数组相同 依然有四种方式
*/
public class Test {
public static void main(String[] args) {
// 方式1 先声明 再开辟空间
int [][] nums1;
nums1 = new int[3][];
nums1[0] = new int[5];
nums1[0][0] = 11;
nums1[0][1] = 12;
nums1[0][2] = 13;
nums1[0][3] = 14;
nums1[0][4] = 15;
nums1[1] = new int[2];
nums1[1][0] = 55;
nums1[1][1] = 66;
nums1[2] = new int[3];
nums1[2][0] = 78;
nums1[2][1] = 73;
nums1[2][2] = 74;
// 方式2 连声明 带开辟空间
int [][] nums2 = new int[5][4];
// 方式3 连声明带赋值 繁琐
int [][] nums3 = new int[][] {{1,2,3},{78,89},{5}};
// 方式4 连声明带赋值 简单
int [][] nums4 = {{1,2,3},{78,89},{5}};
}
}
遍历二维数组
/**
* 遍历二维数组
*/
public class Test {
public static void main(String[] args) {
int [][] nums1;
nums1 = new int[3][];
nums1[0] = new int[5];
nums1[0][0] = 11;
nums1[0][1] = 12;
nums1[0][2] = 13;
nums1[0][3] = 14;
nums1[0][4] = 15;
nums1[1] = new int[2];
nums1[1][0] = 55;
nums1[1][1] = 66;
nums1[2] = new int[3];
nums1[2][0] = 78;
nums1[2][1] = 73;
nums1[2][2] = 74;
for (int i = 0; i < nums1.length; i++) {
// System.out.println(nums1[i]);
for(int j = 0;j < nums1[i].length;j++) {
System.out.println(nums1[i][j]);
}
}
}
}