a.
一维数组
概念
对数组操作最基本的动作就是存和取。
核心思想
就是对角标的操作。
动态初始化
int[] arr = new int[6];
静态初始化
int[] arr = new int[]{3,5,66,7,8};
int[] arr = {3,5,66,7,8};
用于存储同种数据类型的多个值。
概念:
* 数组是存储同一种数据类型的多个元素的集合,可以看做一个容器。
* 数组可以是基本数据类型,也可以是引用数据类型。
p.s.
数组的好处:
可以自动给数组中你的元素从0开始编号,方便操作这些元素。
格式:
数组类型[] 数组名 = new 数组类型[数组的长度];
int[] arr = new int[5];
解释:
左边:
int: 数据类型
[]: 代表数组,[]个中括号,就代表几维数组。
arr: 数组名,即合法标识符。
右边:
new: 创建一个新的实体或对象
int: 数据类型
[]: 代表数组
5: 代表数组的长度,表示能存入几个数据。
b.
数组的初始化
就是为数组开辟连续的内存空间,并为每个数组的元素赋予值。
如何对数组进行初始化
初始化分两种:
* 动态初始化:
* 只指定长度,由系统给出初始值。
* 数据类型[] 数组名 = new 数据类型[数组长度];
* int[] a = new int[5];
* 解释:
* 首先会创建new int[5],会记录一个地址值,将地址值给arr。
* 静态初始化:
* 给出初始值,根据初始化值的个数,由系统决定长度。
* 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
默认初始化值:
整数类型:byte,short,int,long 默认初始化值都是:0
浮点类型:float,double 默认初始化值都是:0.0
Boolean类型: 默认初始化值是false
字符类型:char,默认初始化值: '\u0000'
char在内存中的占2个字节, 是16个二进制位。
u0000中的每个0代表的是16进制的0,那么四个0就是代表16个二进制。
int[] arr = new int[4];
System.out.println(arr); //[I@1db9742
解释:[I@1db9742
[:代表数组,几个就代表几维,现在是一个二维数组。
I:表示是int类型的数据类型。
@:固定的。
1db9742:哈希code地址值,是一个十六值形式的地址值。
double[] d = new double[5];
System.out.println(d); //[D@1db9742
解释:[D@1db9742
[ 代表数组,几个就代表几维
D 表示数据类型
@ 固定写法
1db9742 哈希code,代表一个十六进制的地址值。
p.s.
java程序在运行的时候,需要在内存中分配空间,为了提高运行效率,又对空间进行了不同区域的划分,因为每一片区域都有特点的处理数据方式和内存管理方式。
c.
内存的分配 和 栈堆的区别?
分配:(5个)
栈: 存储局部变量
* 局部变量: 定义在方法声明上或方法中的。
堆: 存储new出来的数组或对象
方法区: 面向对象时再说
本地方法区: 跟系统有关
寄存器: 给cpu用的
比如:
.class文件, javac后,生成一个.class文件,该文件在硬盘中,当java的时候,.class由硬盘进入内存中。 然后程序里面的具体代码,分别进入内存中的分配中,如局部变量进栈,new出来的数字或对象进堆等等等等。
p.s.
栈内存:
用于存储局部变量和方法,当变量和方法所属的作用域一旦结束,所占空间会自动释放。
堆内存:
数组和对象,通过new建立的实例都存放在堆内存中。
每个实体都有内存地址值。
实体中的变量都有默认初始化值,根据类型的不同而不同,如整数类型是0,小数类型是0.0或0.0f,Boolean类型是false,char类型是'\u0000'
如果将数字的引用实体设置为null,也就是实体不再被使用,那么会在不确定的时间内被垃圾号机制给回收掉。
静态初始化:
格式:
数据类型[] 数据名 = new 数据类型[多少个];
int[] arr = new int[6];
例子:
三个引用,有两个数组的引用指向同一个地址
int[] arr1 = new int[3]; //[I@da6bf4
int[] arr2 = new int[4]; //[I@1eb97b8
int[] arr3 = arr2; //都是指向同一个地址值,即[I@1eb97b8。
这就是三个引用,两个数组。
静态初始化:
格式:
数据类型[] 数据名 = new 数据类型[]{元素1,元素2,...};
简化格式:
数据类型[] 数据名 = {元素1,元素2,...};
二者的区别:
int[] arr = new int[]{5,6,7,8}; //规矩写法
int[] arr2 = {4,5,6,78}; //简写
分行写:
规矩写法
int[] arr;
arr = new int[]{5,6,7,8}; //正确
简写
int[] arr2;
arr2 = {4,5,6,78}; //错误
所以说
规矩写法: 可以先声明,后赋值。
简写: 只能写在一行。
例子:
int[] arr = new int[]{1,2,3,4,5};
int[] arr2 = {6,7,8,9,10};
System.out.println(arr);//地址值
System.out.println(arr[0]);//1
可以写成二行:
int[] arrs;
arrs = new int[]{1,2,3,4,5};
System.out.println(arrs[3]);//4 这里[]中的数字,代表的是索引数。
//只能写一行
//int[] arrs2;
//arrs2 = {22,4,55,43};//报错, 只能写成一行。
//不能动静结合
//int[] arr = new int[5]{1,2,3,4,5};
d.
数组中存在的问题:
* 角标越界
* ArrayIndexOutofBoundsException: 数组索引越界异常
* 原因: 访问了不存在的索引。
例子:
int[] arr = new int[6];
System.out.println(arr[5]); //0
System.out.println(arr[6]); //报错,因为6是不存在的索引。
* 空指针
*
* PointerException: 空指针异常
* 原因:数组越界不在指向堆内存,而你还继续使用该数组名去访问元素。
例子:
int[] arr2 = new int[5];
arr2 = null; //因为已被nul已覆盖,地址值不存在了。
System.out.println(arr2[0]);//不存在,异常。
e.
数组的遍历
数组的遍历:就是依次输出数组中的每个元素的值。
数组的属性:arr.length 数组的长度。
最大的索引:arr.length-1
* 最大长度就是最大索引数,即arr.length-1。
例子:
class Demo6_数组_一维数组的遍历 {
public static void main(String[] args) {
int[] arr = new int[]{33,54,22,53,23};
for (int z = 0;z<arr.length ;z++ ) {
System.out.println(arr[z]);
}
//使用方法来做
int[] aa = new int[5];
int[] bb = new int[]{4,6,7,8,9};
Arr(aa); // 0 0 0 0 0
Arr(bb); // 4 6 7 8 9
}
//使用方法来便利获取多个数组的元素、
public static void Arr(int[] arrs){
for (int i = 0;i<arrs.length ;i++ ) {
System.out.print(arrs[i]+" ");
}
}
}
p.s.
数组操作常见问题
数组角标越界异常:ArrayIndexOfBoundsException: 访问了数组中不存在的角标时而发生的异常。
空指针异常: NullPointerException: 当引用型变量没有指向任何实体时,用其操作给实体,就会发生这样的异常。
f.
获取数组中的最大值和最小值
class Demo7_数组_一维数组_获取数组中的最大值最小值 {
public static void main(String[] args) {
int[] arr1 = {33,4,5,6,77,88,79};
int[] arr2 = {55,66,88,90,3,2,1};
getMax(arr1);
getMax(arr2);
getMin(arr1);
getMin(arr2);
}
//获取数组中的最大元素
public static void getMax(int[] arr){
int max=arr[0]; // 对应初始化值,用于记录元素中的第一个值。
for (int i =1; i< arr.length ;i++ ) { // 从数组的第二个元素开始遍历。
if(max<arr[i]){ // 如果max每次记录的数都小于数组中的元素。
max = arr[i]; // max就记录较大的值。
}
}
System.out.println("最大值:"+max);
}
//获取数组中的最小元素
public static void getMin(int[] arrs){
int min = arrs[0]; // 对应初始化值,用于记录元素中的第一个值。
for (int i =1;i<arrs.length ;i++ ) { // 从数组的第二个元素开始遍历
if(min>arrs[i]){ // 【如果每次arr[i]中的值都小于min,】
min = arrs[i]; // min就记录较小的值。
}
}
System.out.println("最小值:"+min);
}
}
g.
数组的反转
class Demo8_数组_一维数组_的反转 {
public static void main(String[] args) {
/*
数组元素反转(就是把元素对调)
i<arr.length/2 表示循环的次数
*/
int[] arr = new int[]{33,44,55,66,77,88,99};
reverse(arr);
}
public static void reverse(int[] arr){
for (int i = 0; i<arr.length/2; i++ ) {//arr.length/2表示循环的次数:两两交换,是索引的2分之一倍
//反转过程 根据两个数交换的原理来做, 定义第三方变量。
/*
arr[0] 和 arr[arr.length-1-0]交换
arr[1] 和 arr[arr.length-1-1]交换
arr[2] 和 arr[arr.length-1-2]交换
*/
int temp = arr[i]; // 定义临时变量,将arr[i]给临时变量。
arr[i] = arr[arr.length-1-i]; // arr[1] 和 arr[arr.length-1-1]交换
arr[arr.length-1-i] = temp; //
//上面的只是将原结果给交换了位置,但并没有输出结果,所以还需要遍历出结果。
}
//遍历结果
print(arr);
}
//遍历反转后的数组。
public static void print(int[] arr){
for (int i=0; i<arr.length; i++ ) { //int i=0表示从0开始遍历。记住 数组的属性:arr.length 数组的长度。
//最大的索引:arr.length-1
System.out.print(arr[i]+" ");
}
}
}
h.
数组的基本查表法
class Demo9_数组_一维数组_的数组查表法 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// in表示输入的意思。
/*
A:案例演示
* 数组查表法(根据键盘录入索引,查找对应星期)
*/
System.out.println("数组查表法(根据键盘录入索引,查找对应星期)1~7的范围内");
int num = sc.nextInt();
//方法一
char weeks = getWeek(num); //这里接收的类型跟方法的类型一致,因为想输出的结果是汉字。
System.out.println("星期:"+weeks);
//方法二
System.out.println("星期:"+getWeek2(num));
}
// 方法一
public static char getWeek(int weeki){//数据类型定义为char,是想输出的结果是汉字。
//定义char,因为结果输出的结果也能是汉字,
char[] week = new char[]{' ','一','二','三','四','五','六','七'}; //因为输入的结果是只能是1~7的范围,但是0对应的索引是一,1对应的索引是二,所以要在前面再加个元素即'',这样输入的数字都能够对应上星期了。
return week[weeki];
}
// 方法二
public static char getWeek2(int weeki){//数据类型定义为char,是想输出的结果是汉字。
//定义char,因为结果输出的结果也能是汉字,
char[] week = new char[]{'一','二','三','四','五','六','七'};
return week[weeki-1]; //这里也可以让索引值-1,就能得到对应的星期。
}
// 方法三
public static String getWeek2(int weeki){//参数类型定义为string,是想输出的结果是汉字即字符串。
String[] week = new String[]{"星期一","星期二","星期三","星期四","星期五","星期六","星期天"};
return week[weeki-1]; //这里也可以让索引值-1,就能得到对应的星期。
}
}
i.
元素出现的索引位置和总次数
class Demo10_数组_一维数组_数组的基本查找_指定元素在索引出现的位置和总次数 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// in表示输入的意思。
/*
A:案例演示
* 数组元素查找(查找指定元素第一次在数组中出现的索引和一共出现的次数)
*/
//查找指定元素第一次在数组中出现的索引
int[] arr = new int[]{44,6,7,8,90,4,2,8};
Earr(arr);
System.out.println("请从上面选择一个数进行输入");
//先遍历结果
int num = sc.nextInt();
int result = Arr(arr, num);
System.out.println("指定元素"+num+"第一次在数组中出现的索引是:"+result);
//查找指定元素在数组中出现的总次数
int sum = getIndex(arr,num);
System.out.println("指定元素"+num+"数组中出现的总次数是:"+sum);
}
//遍历结果
public static void Earr(int[] arr){
for (int i=0; i<arr.length; i++ ) {
System.out.print(arr[i]+" ");
}
}
//查找指定元素第一次在数组中出现的索引
public static int Arr(int[] arr, int value){
for (int i=0; i<arr.length ; i++ ) {
if(arr[i] == value){
return i;
}
}
return -1;
}
//元素在数组中出现的总次数
public static int getIndex(int[] arr,int value){
int count = 0; //定义计数器,用来计算元素出现的总次数
for (int i = 0; i<arr.length; i++ ) {
if(arr[i] == value){
count++;
}
}
return count;
}
}
j.
二维数组
格式:
int[][] arr = new int[3][2]; 且索引都是从【0】开始的。
arr[0] 表示二维数组中的第一个一维数组
arr[0][1]表示二维数组中的第一个一维数组的第二个元素
怎么读?
1)这是一个二维数组
2)且这个二维数组中定义了3个一维数组
3)最后这个一维数组中都有两个元素。
多种格式:
int[][] arr = new int[3][4]; 最常用。
int[] arr[] = new int[4][5];
int arr[][] = new int[5][7];
第一种最常用, new int[5][7]形式都不变。
a. 常规形式
int[][] arr = new int[3][]; 二维数组,声明三个一维数组,但都没有指定元素个数。
arr[0] = new int[2]; 声明第一个一维数组有二个int元素
arr[1] = new int[4]; 声明第二个一维数组有四个int元素
arr[2] = new int[3]; 声明第三个一维数组有三个int元素
b. 简写形式
int[][] arr = {{3,5,6},{2,4},{5,5,6},{7,9,23}}; 二维数组,声明了4个一维数组。
第一个一维数组有3个int元素
第二个一维数组有2个int元素
第三个一维数组有3个int元素
第四个一维数组有3个int元素
注意下面定义的区别
int x;
int y;
int x,y; xy同时说明为一个int类型。
int[] x; 声明一个一维数组
int[] y[]; 声明一个二维数组
int[] x,y[]; x是一维数组,y是二维数组
//可以看做:
//int[] x; 是一维数组
//int[] y[] 是二维数组
例子:
案例演示
* 定义二维数组,输出二维数组名称,一维数组名称,一个元素
int[][] arr = new int[3][4]; // 定义二维数组
System.out.println(arr); // 输出二维数组名称
System.out.println(arr[2]); // 二维数组中的第三个一维数组
System.out.println(arr[2][1]); // 第三个一维数组的第二个元素
//[[I@16d3586 二维数组的地址值
//[I@154617c 一维数组的地址值
//0 一维数组的第二个元素的默认值
记住: 数组是引用数据类型的,默认值是null。
例子:
需求:公司年销售额求和
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
class Demo14_数组_二维数组_公司季度销售额求和 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// in表示输入的意思。
/*
需求:公司年销售额求和
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
*/
int[][] arr = {{22,66,44},{77,33,88},{25,45,65},{11,66,99}};
twoArray2(arr);
}
//求 总季度的总额
public static int twoArray(int[][] arr){
int sum =0; //定义变量,用于记录4个季度的总额
for (int i = 0;i<arr.length;i++ ) {
for (int j =0;j<arr[i].length ;j++ ) {
sum+=arr[i][j]; //累加
//System.out.print(arr[i][j]+" "); //输出总额
}
}
return sum;
}
//求单个季度的总额 和 总季度的和
public static void twoArray2(int[][] arr){
int sum =0; //定义变量,用于记录单个季度的总额
for (int i = 0;i<arr.length;i++ ) {
for (int j =0;j<arr[i].length ;j++ ) {
if(arr[i] == arr[i]){ //如果当前一维数组 == 一维数组
sum+=arr[i][j]; //累加
System.out.print(arr[i][j]+" ");
}
else{
sum+=arr[i][j];
System.out.print(arr[i][j]+" ");
}
}
System.out.println("每个季度的单独总额:"+sum);
sum=0; //每个单独的季度计算出结果后,单个额度的总额度清0
}
int result = twoArray(arr);
System.out.println("4个季度的总额:"+result);
}
k.
思考题Java中的参数传递问题及图解
class Demo15_数组_思考题Java中的参数传递问题及图解{
//看程序写结果,并画内存图解释
public static void main(String[] args) {
int a = 10;
int b = 20;
/*
System.out.println("a:"+a+",b:"+b); // a=10 b=20 对
//int是基本数据类型
change(a,b); //基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失【局部变量在栈内存】
System.out.println("a:"+a+",b:"+b); //a=20,b=40为什么错?正确:a=10,b=20 这里涉及方法调用完后弹栈的问题。 因为change(a,b)输出完结果后,就会被弹栈,且这句a,b的就是上面定义的值,即a=10,b=20。
*/
//数组是引用数据类型
//
int[] arr = {1,2,3,4,5};
change(arr); //结果: 1 4 3 8 5
//引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存数组对象还在,可以通过【地址继续访问堆内存中的值】
System.out.println("arr[1]的值是:"+arr[1]); //4
}
public static void change(int a,int b) {
System.out.println("a:"+a+",b:"+b); //a=10,b=20 对
a = b; //a=20
b = a + b; //b=40
System.out.println("a:"+a+",b:"+b); //a=20,b=40 对
}
public static void change(int[] arr) {
for(int x=0; x<arr.length; x++) { //索引 索引对应的值 是否进入if arr结果
if(arr[x]%2==0) { // 0 1 不进 1
arr[x]*=2; // 1 2 进 2*2=4
} // 2 3 不进 3
System.out.print(arr[x]+" "); // 3 4 进 4*2=8
} // 4 5 不进 5
System.out.println();
}
}
【注意 经典问题】
* 基本数据类型的值传递,不改变原值,因为方法调用后会被弹栈,方法中的局部变量也跟着方法消失。【方法变量都在栈内存】
* 引用数据类型的值传递,改变原值,因为即使方法调后会被弹栈,但堆内存中的对象或数组还存在,仍然可以通过地址值来访问堆内存中的数据。
java中是'值'传递还是'址'传递。
说法一:都传递,因为基本数据类型传递的是值,引用数据类型传递的是地址。
说法二:只传递值,因为地址值也是值,因为支持者是:詹姆斯·高斯林
一维数组
概念
对数组操作最基本的动作就是存和取。
核心思想
就是对角标的操作。
动态初始化
int[] arr = new int[6];
静态初始化
int[] arr = new int[]{3,5,66,7,8};
int[] arr = {3,5,66,7,8};
用于存储同种数据类型的多个值。
概念:
* 数组是存储同一种数据类型的多个元素的集合,可以看做一个容器。
* 数组可以是基本数据类型,也可以是引用数据类型。
p.s.
数组的好处:
可以自动给数组中你的元素从0开始编号,方便操作这些元素。
格式:
数组类型[] 数组名 = new 数组类型[数组的长度];
int[] arr = new int[5];
解释:
左边:
int: 数据类型
[]: 代表数组,[]个中括号,就代表几维数组。
arr: 数组名,即合法标识符。
右边:
new: 创建一个新的实体或对象
int: 数据类型
[]: 代表数组
5: 代表数组的长度,表示能存入几个数据。
b.
数组的初始化
就是为数组开辟连续的内存空间,并为每个数组的元素赋予值。
如何对数组进行初始化
初始化分两种:
* 动态初始化:
* 只指定长度,由系统给出初始值。
* 数据类型[] 数组名 = new 数据类型[数组长度];
* int[] a = new int[5];
* 解释:
* 首先会创建new int[5],会记录一个地址值,将地址值给arr。
* 静态初始化:
* 给出初始值,根据初始化值的个数,由系统决定长度。
* 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
默认初始化值:
整数类型:byte,short,int,long 默认初始化值都是:0
浮点类型:float,double 默认初始化值都是:0.0
Boolean类型: 默认初始化值是false
字符类型:char,默认初始化值: '\u0000'
char在内存中的占2个字节, 是16个二进制位。
u0000中的每个0代表的是16进制的0,那么四个0就是代表16个二进制。
int[] arr = new int[4];
System.out.println(arr); //[I@1db9742
解释:[I@1db9742
[:代表数组,几个就代表几维,现在是一个二维数组。
I:表示是int类型的数据类型。
@:固定的。
1db9742:哈希code地址值,是一个十六值形式的地址值。
double[] d = new double[5];
System.out.println(d); //[D@1db9742
解释:[D@1db9742
[ 代表数组,几个就代表几维
D 表示数据类型
@ 固定写法
1db9742 哈希code,代表一个十六进制的地址值。
p.s.
java程序在运行的时候,需要在内存中分配空间,为了提高运行效率,又对空间进行了不同区域的划分,因为每一片区域都有特点的处理数据方式和内存管理方式。
c.
内存的分配 和 栈堆的区别?
分配:(5个)
栈: 存储局部变量
* 局部变量: 定义在方法声明上或方法中的。
堆: 存储new出来的数组或对象
方法区: 面向对象时再说
本地方法区: 跟系统有关
寄存器: 给cpu用的
比如:
.class文件, javac后,生成一个.class文件,该文件在硬盘中,当java的时候,.class由硬盘进入内存中。 然后程序里面的具体代码,分别进入内存中的分配中,如局部变量进栈,new出来的数字或对象进堆等等等等。
p.s.
栈内存:
用于存储局部变量和方法,当变量和方法所属的作用域一旦结束,所占空间会自动释放。
堆内存:
数组和对象,通过new建立的实例都存放在堆内存中。
每个实体都有内存地址值。
实体中的变量都有默认初始化值,根据类型的不同而不同,如整数类型是0,小数类型是0.0或0.0f,Boolean类型是false,char类型是'\u0000'
如果将数字的引用实体设置为null,也就是实体不再被使用,那么会在不确定的时间内被垃圾号机制给回收掉。
静态初始化:
格式:
数据类型[] 数据名 = new 数据类型[多少个];
int[] arr = new int[6];
例子:
三个引用,有两个数组的引用指向同一个地址
int[] arr1 = new int[3]; //[I@da6bf4
int[] arr2 = new int[4]; //[I@1eb97b8
int[] arr3 = arr2; //都是指向同一个地址值,即[I@1eb97b8。
这就是三个引用,两个数组。
静态初始化:
格式:
数据类型[] 数据名 = new 数据类型[]{元素1,元素2,...};
简化格式:
数据类型[] 数据名 = {元素1,元素2,...};
二者的区别:
int[] arr = new int[]{5,6,7,8}; //规矩写法
int[] arr2 = {4,5,6,78}; //简写
分行写:
规矩写法
int[] arr;
arr = new int[]{5,6,7,8}; //正确
简写
int[] arr2;
arr2 = {4,5,6,78}; //错误
所以说
规矩写法: 可以先声明,后赋值。
简写: 只能写在一行。
例子:
int[] arr = new int[]{1,2,3,4,5};
int[] arr2 = {6,7,8,9,10};
System.out.println(arr);//地址值
System.out.println(arr[0]);//1
可以写成二行:
int[] arrs;
arrs = new int[]{1,2,3,4,5};
System.out.println(arrs[3]);//4 这里[]中的数字,代表的是索引数。
//只能写一行
//int[] arrs2;
//arrs2 = {22,4,55,43};//报错, 只能写成一行。
//不能动静结合
//int[] arr = new int[5]{1,2,3,4,5};
d.
数组中存在的问题:
* 角标越界
* ArrayIndexOutofBoundsException: 数组索引越界异常
* 原因: 访问了不存在的索引。
例子:
int[] arr = new int[6];
System.out.println(arr[5]); //0
System.out.println(arr[6]); //报错,因为6是不存在的索引。
* 空指针
*
* PointerException: 空指针异常
* 原因:数组越界不在指向堆内存,而你还继续使用该数组名去访问元素。
例子:
int[] arr2 = new int[5];
arr2 = null; //因为已被nul已覆盖,地址值不存在了。
System.out.println(arr2[0]);//不存在,异常。
e.
数组的遍历
数组的遍历:就是依次输出数组中的每个元素的值。
数组的属性:arr.length 数组的长度。
最大的索引:arr.length-1
* 最大长度就是最大索引数,即arr.length-1。
例子:
class Demo6_数组_一维数组的遍历 {
public static void main(String[] args) {
int[] arr = new int[]{33,54,22,53,23};
for (int z = 0;z<arr.length ;z++ ) {
System.out.println(arr[z]);
}
//使用方法来做
int[] aa = new int[5];
int[] bb = new int[]{4,6,7,8,9};
Arr(aa); // 0 0 0 0 0
Arr(bb); // 4 6 7 8 9
}
//使用方法来便利获取多个数组的元素、
public static void Arr(int[] arrs){
for (int i = 0;i<arrs.length ;i++ ) {
System.out.print(arrs[i]+" ");
}
}
}
p.s.
数组操作常见问题
数组角标越界异常:ArrayIndexOfBoundsException: 访问了数组中不存在的角标时而发生的异常。
空指针异常: NullPointerException: 当引用型变量没有指向任何实体时,用其操作给实体,就会发生这样的异常。
f.
获取数组中的最大值和最小值
class Demo7_数组_一维数组_获取数组中的最大值最小值 {
public static void main(String[] args) {
int[] arr1 = {33,4,5,6,77,88,79};
int[] arr2 = {55,66,88,90,3,2,1};
getMax(arr1);
getMax(arr2);
getMin(arr1);
getMin(arr2);
}
//获取数组中的最大元素
public static void getMax(int[] arr){
int max=arr[0]; // 对应初始化值,用于记录元素中的第一个值。
for (int i =1; i< arr.length ;i++ ) { // 从数组的第二个元素开始遍历。
if(max<arr[i]){ // 如果max每次记录的数都小于数组中的元素。
max = arr[i]; // max就记录较大的值。
}
}
System.out.println("最大值:"+max);
}
//获取数组中的最小元素
public static void getMin(int[] arrs){
int min = arrs[0]; // 对应初始化值,用于记录元素中的第一个值。
for (int i =1;i<arrs.length ;i++ ) { // 从数组的第二个元素开始遍历
if(min>arrs[i]){ // 【如果每次arr[i]中的值都小于min,】
min = arrs[i]; // min就记录较小的值。
}
}
System.out.println("最小值:"+min);
}
}
g.
数组的反转
class Demo8_数组_一维数组_的反转 {
public static void main(String[] args) {
/*
数组元素反转(就是把元素对调)
i<arr.length/2 表示循环的次数
*/
int[] arr = new int[]{33,44,55,66,77,88,99};
reverse(arr);
}
public static void reverse(int[] arr){
for (int i = 0; i<arr.length/2; i++ ) {//arr.length/2表示循环的次数:两两交换,是索引的2分之一倍
//反转过程 根据两个数交换的原理来做, 定义第三方变量。
/*
arr[0] 和 arr[arr.length-1-0]交换
arr[1] 和 arr[arr.length-1-1]交换
arr[2] 和 arr[arr.length-1-2]交换
*/
int temp = arr[i]; // 定义临时变量,将arr[i]给临时变量。
arr[i] = arr[arr.length-1-i]; // arr[1] 和 arr[arr.length-1-1]交换
arr[arr.length-1-i] = temp; //
//上面的只是将原结果给交换了位置,但并没有输出结果,所以还需要遍历出结果。
}
//遍历结果
print(arr);
}
//遍历反转后的数组。
public static void print(int[] arr){
for (int i=0; i<arr.length; i++ ) { //int i=0表示从0开始遍历。记住 数组的属性:arr.length 数组的长度。
//最大的索引:arr.length-1
System.out.print(arr[i]+" ");
}
}
}
h.
数组的基本查表法
class Demo9_数组_一维数组_的数组查表法 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// in表示输入的意思。
/*
A:案例演示
* 数组查表法(根据键盘录入索引,查找对应星期)
*/
System.out.println("数组查表法(根据键盘录入索引,查找对应星期)1~7的范围内");
int num = sc.nextInt();
//方法一
char weeks = getWeek(num); //这里接收的类型跟方法的类型一致,因为想输出的结果是汉字。
System.out.println("星期:"+weeks);
//方法二
System.out.println("星期:"+getWeek2(num));
}
// 方法一
public static char getWeek(int weeki){//数据类型定义为char,是想输出的结果是汉字。
//定义char,因为结果输出的结果也能是汉字,
char[] week = new char[]{' ','一','二','三','四','五','六','七'}; //因为输入的结果是只能是1~7的范围,但是0对应的索引是一,1对应的索引是二,所以要在前面再加个元素即'',这样输入的数字都能够对应上星期了。
return week[weeki];
}
// 方法二
public static char getWeek2(int weeki){//数据类型定义为char,是想输出的结果是汉字。
//定义char,因为结果输出的结果也能是汉字,
char[] week = new char[]{'一','二','三','四','五','六','七'};
return week[weeki-1]; //这里也可以让索引值-1,就能得到对应的星期。
}
// 方法三
public static String getWeek2(int weeki){//参数类型定义为string,是想输出的结果是汉字即字符串。
String[] week = new String[]{"星期一","星期二","星期三","星期四","星期五","星期六","星期天"};
return week[weeki-1]; //这里也可以让索引值-1,就能得到对应的星期。
}
}
i.
元素出现的索引位置和总次数
class Demo10_数组_一维数组_数组的基本查找_指定元素在索引出现的位置和总次数 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// in表示输入的意思。
/*
A:案例演示
* 数组元素查找(查找指定元素第一次在数组中出现的索引和一共出现的次数)
*/
//查找指定元素第一次在数组中出现的索引
int[] arr = new int[]{44,6,7,8,90,4,2,8};
Earr(arr);
System.out.println("请从上面选择一个数进行输入");
//先遍历结果
int num = sc.nextInt();
int result = Arr(arr, num);
System.out.println("指定元素"+num+"第一次在数组中出现的索引是:"+result);
//查找指定元素在数组中出现的总次数
int sum = getIndex(arr,num);
System.out.println("指定元素"+num+"数组中出现的总次数是:"+sum);
}
//遍历结果
public static void Earr(int[] arr){
for (int i=0; i<arr.length; i++ ) {
System.out.print(arr[i]+" ");
}
}
//查找指定元素第一次在数组中出现的索引
public static int Arr(int[] arr, int value){
for (int i=0; i<arr.length ; i++ ) {
if(arr[i] == value){
return i;
}
}
return -1;
}
//元素在数组中出现的总次数
public static int getIndex(int[] arr,int value){
int count = 0; //定义计数器,用来计算元素出现的总次数
for (int i = 0; i<arr.length; i++ ) {
if(arr[i] == value){
count++;
}
}
return count;
}
}
j.
二维数组
格式:
int[][] arr = new int[3][2]; 且索引都是从【0】开始的。
arr[0] 表示二维数组中的第一个一维数组
arr[0][1]表示二维数组中的第一个一维数组的第二个元素
怎么读?
1)这是一个二维数组
2)且这个二维数组中定义了3个一维数组
3)最后这个一维数组中都有两个元素。
多种格式:
int[][] arr = new int[3][4]; 最常用。
int[] arr[] = new int[4][5];
int arr[][] = new int[5][7];
第一种最常用, new int[5][7]形式都不变。
a. 常规形式
int[][] arr = new int[3][]; 二维数组,声明三个一维数组,但都没有指定元素个数。
arr[0] = new int[2]; 声明第一个一维数组有二个int元素
arr[1] = new int[4]; 声明第二个一维数组有四个int元素
arr[2] = new int[3]; 声明第三个一维数组有三个int元素
b. 简写形式
int[][] arr = {{3,5,6},{2,4},{5,5,6},{7,9,23}}; 二维数组,声明了4个一维数组。
第一个一维数组有3个int元素
第二个一维数组有2个int元素
第三个一维数组有3个int元素
第四个一维数组有3个int元素
注意下面定义的区别
int x;
int y;
int x,y; xy同时说明为一个int类型。
int[] x; 声明一个一维数组
int[] y[]; 声明一个二维数组
int[] x,y[]; x是一维数组,y是二维数组
//可以看做:
//int[] x; 是一维数组
//int[] y[] 是二维数组
例子:
案例演示
* 定义二维数组,输出二维数组名称,一维数组名称,一个元素
int[][] arr = new int[3][4]; // 定义二维数组
System.out.println(arr); // 输出二维数组名称
System.out.println(arr[2]); // 二维数组中的第三个一维数组
System.out.println(arr[2][1]); // 第三个一维数组的第二个元素
//[[I@16d3586 二维数组的地址值
//[I@154617c 一维数组的地址值
//0 一维数组的第二个元素的默认值
记住: 数组是引用数据类型的,默认值是null。
例子:
需求:公司年销售额求和
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
class Demo14_数组_二维数组_公司季度销售额求和 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);// in表示输入的意思。
/*
需求:公司年销售额求和
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
*/
int[][] arr = {{22,66,44},{77,33,88},{25,45,65},{11,66,99}};
twoArray2(arr);
}
//求 总季度的总额
public static int twoArray(int[][] arr){
int sum =0; //定义变量,用于记录4个季度的总额
for (int i = 0;i<arr.length;i++ ) {
for (int j =0;j<arr[i].length ;j++ ) {
sum+=arr[i][j]; //累加
//System.out.print(arr[i][j]+" "); //输出总额
}
}
return sum;
}
//求单个季度的总额 和 总季度的和
public static void twoArray2(int[][] arr){
int sum =0; //定义变量,用于记录单个季度的总额
for (int i = 0;i<arr.length;i++ ) {
for (int j =0;j<arr[i].length ;j++ ) {
if(arr[i] == arr[i]){ //如果当前一维数组 == 一维数组
sum+=arr[i][j]; //累加
System.out.print(arr[i][j]+" ");
}
else{
sum+=arr[i][j];
System.out.print(arr[i][j]+" ");
}
}
System.out.println("每个季度的单独总额:"+sum);
sum=0; //每个单独的季度计算出结果后,单个额度的总额度清0
}
int result = twoArray(arr);
System.out.println("4个季度的总额:"+result);
}
k.
思考题Java中的参数传递问题及图解
class Demo15_数组_思考题Java中的参数传递问题及图解{
//看程序写结果,并画内存图解释
public static void main(String[] args) {
int a = 10;
int b = 20;
/*
System.out.println("a:"+a+",b:"+b); // a=10 b=20 对
//int是基本数据类型
change(a,b); //基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失【局部变量在栈内存】
System.out.println("a:"+a+",b:"+b); //a=20,b=40为什么错?正确:a=10,b=20 这里涉及方法调用完后弹栈的问题。 因为change(a,b)输出完结果后,就会被弹栈,且这句a,b的就是上面定义的值,即a=10,b=20。
*/
//数组是引用数据类型
//
int[] arr = {1,2,3,4,5};
change(arr); //结果: 1 4 3 8 5
//引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存数组对象还在,可以通过【地址继续访问堆内存中的值】
System.out.println("arr[1]的值是:"+arr[1]); //4
}
public static void change(int a,int b) {
System.out.println("a:"+a+",b:"+b); //a=10,b=20 对
a = b; //a=20
b = a + b; //b=40
System.out.println("a:"+a+",b:"+b); //a=20,b=40 对
}
public static void change(int[] arr) {
for(int x=0; x<arr.length; x++) { //索引 索引对应的值 是否进入if arr结果
if(arr[x]%2==0) { // 0 1 不进 1
arr[x]*=2; // 1 2 进 2*2=4
} // 2 3 不进 3
System.out.print(arr[x]+" "); // 3 4 进 4*2=8
} // 4 5 不进 5
System.out.println();
}
}
【注意 经典问题】
* 基本数据类型的值传递,不改变原值,因为方法调用后会被弹栈,方法中的局部变量也跟着方法消失。【方法变量都在栈内存】
* 引用数据类型的值传递,改变原值,因为即使方法调后会被弹栈,但堆内存中的对象或数组还存在,仍然可以通过地址值来访问堆内存中的数据。
java中是'值'传递还是'址'传递。
说法一:都传递,因为基本数据类型传递的是值,引用数据类型传递的是地址。
说法二:只传递值,因为地址值也是值,因为支持者是:詹姆斯·高斯林