JAVA数组
1.数组格式说明
-
数组是一个储存变量的容器且变量类型一致
-
可储存基本数据类型也可储存变量
-
定义格式
-
数据类型[] 数组名;
-
数据类型 数组名[];
-
int[] x; 定义了一个int类型的数组x
-
int x[]; 定义了一个int类型的x数组
-
一般使用第一种
-
数组必须先初始化才能使用(开辟空间)
-
int[] x=new 数据类型[数据长度] 动态初始化
-
给出初始化值,由系统决定长度 静态初始化
-
int[] x = new int[3]; x[0]=10; x[1]=20; x[2]=30; int num1=x[2]; System.out.println(num1); 定义了一个int类型的数组x,这个数组可以存放3个int类型的值。
-
2.栈和堆
-
栈: 存放的是局部变量
局部变量:在方法定义中或者方法声明上的变量都是局部变量。
-
堆: 存放的是所有new出来的东西(被新定义的)
- 每一个new出来的东西都会为其分配一个地制值。
- 每一个变量都有一个默认的值
- byte,short,int,long – 0
- float,double – 0.0
- char – ‘\u0000’(空字符)
- boolean – false
- 引用数据类型 – null
- 使用完毕就变成了垃圾,等待垃圾回收器对其回收
-
方法区:(面向对象部分讲解)
-
本地方法区:(和系统相关)
-
寄存器:(cpu使用)
3.数组的内存图解
-
将new中的地址和数据放入堆中,再从栈中引用
-
定义的方法放入方法区
-
若引用已被定义的数组再重新赋值,则覆盖掉原有值(没重新开辟新内存)
class Shuzu{ public static void main(String[] args){ int[] arr1=new int[2]; arr1[0]=15; arr1[1]=30; int[] arr2=new int[2]; arr2[0]=40; arr2[1]=50; int[] arr3=arr2; arr3[0]=500; } } 输出arr1[0]=500 arr3[1]=30 arr1的地址已经被arr3所覆盖了
4.静态初始化
-
静态初始化的格式
-
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
int[] arr = new int[]{1,2,3};
常规格式 -
数据类型[] 数组名 = {元素1,元素2,…}; int[] arr = {1,2,3}; 简化格式
-
5.越界和空指针
-
数组索引越界异常(ArrayIndexOutOfBoundsException)
原因:你访问了不存在的索引。int[] arr=new int[2]; System.out.println(arr[3]); 数组角标越界异常,超过了数组定义的长度
-
空指针异常(NullPointerException)
原因:数组已经不在指向堆内存了。而你还用数组名去访问元素。int[] arr=new int[2]; arr=null; System.out.println(a11(1)); 出错,地址的指向已经被断掉了 指为了空指针 有利于垃圾处理器尽早回收
6.数组的操作
-
遍历
-
就是依次输出数组中的每一个元素。
-
for(int i=0;i<arr.length;i++){ System.out.println(arr(i)); }
-
-
获取最值
class Shuzu { public static void main(String[] args) { int[] arr={30,40,50,60}; int max=0; for(int i=0;i<arr.length-1;i++){ if(arr[i]<arr[i+1]){ max=arr[i+1]; }else{ max=arr[i]; } } System.out.println("max="+max); } } 注意i不能超过数组长度-1
-
反向遍历
for(int j=arr.length-1;j>=0;j--){ System.out.println(arr[j]); } 注意arr.length-1
-
反转
-
数组元素反转
class Shuzu { public static void main(String[] args){ int[] arr={30,40,50,60,70}; int a=0; for(int i=0,j=arr.length-1;i<j;i++,j--){ a=arr[i]; arr[i]=arr[j]; arr[j]=a; } for(int k=0;k<arr.length;k++){ System.out.println(arr[k]); } } } 同时在for循环里定义两个变量,在两者大小交汇时停止变换
-
-
查表法
-
数组查表法(根据键盘录入索引,查找对应星期)
public class MyTest { public static void main(String[] args) { String[] weeks = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"}; Scanner sc = new Scanner(System.in); System.out.println("请输入一个索引 0--6"); int index = sc.nextInt(); String ele = getEleByIndex(weeks, index); System.out.println("你要查找的元素是:" + ele); } public static String getEleByIndex(String[] arr, int index) { if (index >= 0 && index <= 6) { String ele = arr[index]; return ele; } else { return "你的索引输入不正确"; } } }
-
-
基本查找
-
数组元素查找(查找指定元素第一次在数组中出现的索引)
import java.util.Scanner; public class input3 { public static void main(String[] args) { String[] weeks = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"}; Scanner sc = new Scanner(System.in); System.out.println("请输入星期,例如输入 星期一"); String xingqi = sc.nextLine(); int s=shu(weeks,xingqi); System.out.println(s); } public static int shu(String[] arr,String ele){ int index=-1; for(int i=0;i<arr.length;i++){ if (ele.equals(arr[i])) { return i; } } return index;} } } 搞清楚方法需要定义几个形参,即想清楚主函数需要几个形参 使用一个if语句判断相等关系从而判断是否输出 ele.equals(arr[i])
-
7.二维数组
(1)二维数组概述和格式
数据类型[][] 变量名 = new 数据类型[m][n];
m表示这个二维数组有多少个一维数组 必须写上
n表示每一个一维数组的元素个数 可选
int[][] arr = new int[3][2];
(2)二维数组另一种格式
数据类型[][] 变量名 = new 数据类型[m][];
可以动态的给出一维数组的数量
int[][] arr = new int[3][];
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
一维数组的长度不尽相同
(3)二维数组第三种格式
数据类型[][] 变量名 = {{元素…},{元素…},{元素…}};
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
int[][] arr = {{1,2,3},{5,6},{7}};
实际为二维数组的静态初始化
(4)二维数组练习——遍历
package ss;
public class yi {
public static void main(String[] args) {
int[][] arr={{2,3,4,5},{2,3,4,6},{3,7,8,9}};
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
System.out.println(arr[i][j]);
}
}
}
}
(5)二维数组练习——求和
需求:公司年销售额求和
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
public class qiuhe {
public static void main(String[] args) {
int[][] arr={{22,66,44},{77,33,88},{25,45,65},{11,66,99}};
int sum=0;
for(int i=0;i<arr.length;i++){
sum=0;
for(int j=0;j<arr[i].length;j++){
sum+=arr[i][j];
}
System.out.println(sum);
}
}
}
注意需要每次循环将sum置零
B:需求:打印杨辉三角形(行数可以键盘录入)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
package ss;
public class yanghui {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入行数");
int x = sc.nextInt();
int[][] arr = new int[x][];
for (int i = 0; i < x; i++) {
arr[i] = new int[i + 1];//给一维数组定义长度
for (int j = 0; j < i+1; j++) {
if (i==0||j == 0||i==j) {
arr[i][j] = 1;
} else {
arr[i][j] = arr[i - 1][j-1] + arr[i - 1][j];
}
}
}
for (int K = 0; K < arr.length; K++) {
for (int S = 0; S < arr[K].length; S++) {
System.out.print(arr[K][S]+" ");
}
System.out.println();
}
}
}
8.JAVA中的参数传递问题
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a: " + a + ",b: " + b);
change(a,b);
System.out.println("a: " + a + ",b: " + b);
int[] arr = {1,2,3,4,5};
change(arr);
System.out.println(arr[1]);
}
public static void change(int a,int b) {
System.out.println("a: " + a + ",b: " + b);
a = b;
b = a + b;
System.out.println("a: " + a + ",b: " + b);
}
public static void change(int[] arr){
for(int x = 0 ; x < arr.length ; x++){
if(arr[x]%2 == 0){
arr[x] *= 2;
}
}
}
a=10,b=20;
a=10,b=20;
a=20,b=40;
a=10,b=20;
4
- 基本类型传参——属于值传递,形参的改变不影响实参
- 引用类型传参——属于引用传递,传递的是地址,所有改变会影响主函数
9.递归
- 方法调用中定义本身的方法称为递归
(1)递归求阶乘
package ss;
public class jiecheng {
public static void main(String[] args) {
int num=jiecheng(5);
System.out.println(num);
}
public static int jiecheng(int num1) {
if(num1==1){
return 1;
}else{
return num1*=jiecheng(num1-1);//调用方法本身
}
}
}
递归的思想就是先拆分再合并,先一步一步调用方法,最后达到条件的时候将所有的方法合并起来
(2)兔子问题
月份 兔子对数
1 1
2 1
3 2
4 3
5 5
6 8
7 13
package ss;
public class jiecheng {
public static void main(String[] args) {
int num=tuzi(20);
System.out.println(num);
}
public static int tuzi(int num1) {
int s=0;
if(num1==1||num1==2){
return 1;
}
return s+=tuzi(num1-1)+tuzi(num1-2);
}
}
从第三个数开始,每个数等于上面两个数之和