数组
前言
初学java语言的小白,日常记录个人所学、所思、所感、所获。
请java语言行业的前辈们多多指教, 目前从事汽车制造行业。
属于零基础自学,愿未来自己感谢今天的选择和努力。加油!
一、数组的概念
2021、8、31更新
笔记:
1.数组是一个容器,一次可以存放多个数据值
2.数组内的数据类型必须统一,否则无法构成数组
3.数组的长度在程序运行期间不可改变
/*
数组:一种容器,可以同时存放多个数据值
数组的特点:
1.数组是一种引用类型
2.数组当中有多个数据,类型必须统一
3.数组的长度在程序运行期间不可改变
以存储同学成绩为例:
*/
public class Demo01Array {
public static void main(String[] args) {
//一个变量每次只能存放一个数据
int score1=100;
int score2=98;
int score3=99;
System.out.println(score3);//99
score3=97;
System.out.println(score3);//97
}
}
二、数组的定义格式-动态初始化
2021、8、31更新
笔记:
1.首先牢记动态初始化的格式
动态初始化:(指定数据的长度)
格式:数据类型 [] 数组名称=new 数据类型[数组长度];
/*
创建数组(数组的初始化):在内存当中创建一个数组,并且向其中赋予一些默认值。
常见的两种初始方式:
1.动态初始化;(指定数组的长度)
2.静态初始化:(指定数组的内容)
动态数组初始化格式:
数据类型 [] 数组名称 = new 数据类型[数组长度];
解析含义:
左侧的数据类型:也就是数组当中保存的数据,全都是统一的什么类型。
左侧的中括号:代表我是一个数组。
左侧的数组名称:给数组取一个名称
右侧的new:代表创建数组的动作
右侧的数据类型:必须和左边的数据类型保持一致
右侧中括号的长度;也就是数组当中,到底可以保存多少个数据,【数据的长度是一个int数字】
*/
public class Demo01Array {
public static void main(String[] args) {
//动态初始化数组
//创建一个数组,里面可以存放300个int数据
//格式:数据类型 [] 数组名称 = new 数据类型[数组长度];
int [] arrayA = new int[300];//这就是创建了一个可以存放300个int数据的数组
//创建一个数组,能存放10个double类型的数据。
//格式:数据类型 [] 数组名称 = new 数据类型[数组长度];
double [] arrayB = new double [10];
//创建一个数组,能存放5个字符串数据
//格式:数据类型[]数组名称 = new 数据类型 [数组长度];
String [] arrayC = new String [5];
}
}
三、数组的定义格式-静态初始化
2021、8、31更新
笔记:
注意静态初始化的标准格式;
数据类型[]数组名称 = new 数据类型[]{};
静态初始化其实也能根据大括号内的元素内容得到数据长度
/*
动态初始化(指定长度):在创建数据的时候,直接指定数组当中数据元素的个数。也就是指定长度
静态初始化(指定内容):在创建数组的时候,不直接指定数据的个数多少,而是直接将具体的数据内容进行指定
静态初始化的基本格式:
数据类型[]数组名称 = new 数据类型 []{};
大括号里面的数据用英文的逗号隔开
注意事项:
虽然静态初始化没有直接告诉长度,但是根据大括号里面的元素具体内容,也可以自动推算出长度。
*/
public class Demo02Array {
public static void main(String[] args) {
//直接创建一个数组,里面装的全都是int数字,具体为:5、15、25
int [] arrayA = new int[]{5,15,25,40};
//创建一个数组,用来装字符串"Hello","World","Java"
String [] arrayB = new String []{"Hello","World","Java"};
}
}
四、数组的定义格式-省略格式
2021、9、1更新
笔记:
牢记
动态初始化格式:
数据类型 [] 数组名称 = new 数据类型[数组长度];
静态初始化的基本格式:
数据类型 [] 数组名称 = new 数据类型 [] {数组元素};
静态初始化的省略格式:
数据类型 [] 数组名称 = {数组元素}
/*
使用静态初始化数组的时候,格式还可以省略一下。
标准格式:
数据类型[]数组名称 = new 数据类型[]{元素1,元素2,元素3…}
省略格式:
数据类型[]数组名称 ={元素1,元素2,元素3…}
注意事项:
1.静态初始化没有直接指定长度,但是仍然会自动推算得到的长度
2.静态初始化【标准格式】可以拆分成为两个步骤
3.静态初始化也可以拆分成为两个步骤
4.静态初始化一旦使用省略格式,就不能拆分成为两个步骤了
使用建议:
如果不确定数组当中的具体内容,用动态初始化。
否则,已经确定了数组当中的具体内容,用静态初始化。
*/
public class Demo03Array {
public static void main(String[] args) {
//标准格式静态初始化
int [] arrayA =new int []{10,20,30,40};
//省略格式静态初始化
int [] arrayB = {10,20,30,40};
//静态初始化[标准格式]可以拆分成为两个步骤
int [] arrayC;
arrayC=new int []{10,20,30,40};
//动态初始化
int [] arrayD = new int [10];
//动态初始化也可以拆分成为两个步骤
int[]arrayE;
arrayE=new int [10];
//静态初始化一旦使用省略格式,就不能拆分成为两个步骤了
//错误写法
// int[]arrayG;
// arrayG={10,20,30};
}
}
五、访问数组元素进行获取
2021、9、1更新
笔记:
1、直接打印数组名称得到的只是数组内存地址的哈希值。
2、访问数组的标准格式:数组名称[索引值]。
3、索引值是int数字,代表数组当中元素编号。
4.【注意】:索引值从0开始,一直到“数组长度-1”位置。
/*
直接都打印数组名称,得到的是数组对应的,内存地址哈希值。
二进制:0,1
十进制:0、1、2、3、4、5、6、7、8、9
十六进制:0、1、2、3、4、5、6、7、8、9、a、b、c、d、e、f
访问数组元素的格式:数组名称 [索引值]
索引值:就是一个int数字,代表数组当中元素编号
【注意】:索引值从0开始,一直到"数组长度-1"位置
*/
public class Demo04ArrayUse {
public static void main(String[] args) {
//静态初始化的省略格式
int[] array = {10, 20, 30};
//直接都打印数组名称,得到的是数组对应的,内存地址哈希值。
System.out.println(array);//[I@5acf9800
//解析[I@5acf9800
//[(数组)I(数据类型int)@ 5acf9800(十六进制)
//直接打印数组当中的元素
System.out.println(array[0]);//10
System.out.println("========");
//也可以将数组当中的某一个元素,赋值交给变量。
int num = array[1];
System.out.println(num);
//似乎打印字符的时候不显示地址哈希值?
char[] arrayA = {'你', '我'};
System.out.println(arrayA);//你 我
}
}
六、访问数组元素进行赋值
2021、9、1更新
笔记:
整数类型数组,默认值0
浮点类型数组,默认值0.0
字符类型数组,默认值\u000
布尔类型数组,默认值false
引用类型数组,默认值null
/*
使用动态初始化数组的时候:其中的元素将会自动拥有一个默认值,规则如下:
如果是整数类型,那么默认为0;
如果是浮点类型,那么默认为0.0;
如果是字符类型,那么默认为’\u0000’;//默认为不可见类型,打印输出结果为空
如果为布尔类型,那么默认为false;
如果为引用类型,那么默认为null;
注意事项:
静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值。
即 静态初始化 先等于默认值,再等于大括号当中的具体内容
*/
public class Demo05ArrayUse {
public static void main(String[] args) {
//动态初始化一个数组
int [] array = new int [3];
System.out.println(array);//内存地址哈希值
System.out.println(array[0]);//0
System.out.println(array[1]);//0
System.out.println(array[2]);//0
System.out.println("========");
//将数据123赋值交给数组array当中的1号元素。
array[1] = 123;
System.out.println(array[0]);//0
System.out.println(array[1]);//123
System.out.println(array[2]);//0
}
}
七、Java中内存划分
2021、9、2更新
笔记:
1.栈:局部变量,方法运行在栈当中
2.堆:new出来的东西都在堆当中
3.方法区:.class文件
1.栈(Stack):存放的都是方法当中的局部变量。方法的运行一定要在栈当中运行。
局部变量:方法的参数,或者是方法{}内部的变量。
作用域:一旦超出作用域,立刻从栈内存当中消失。
2.堆(Heap):凡是new出来的东西,都在堆当中。
堆内存里面的东西都有一个地址值;16进制。
堆内存里面的东西都有默认值
默认值
整数:0
浮点:0.0
字符:’\u0000’
布尔:false
String;null
3.方法区(Method Area):存储·class相关信息,包含方法的信息。
4.本地方法栈(Native Method Stack):与操作系统相关
5.寄存器(pc Register):与cpu相关
八、一个数组的内存图
2021、9、2更新
笔记:
注意理解下图
public class Demo06ArrayOne {
public static void main(String[] args) {
int [] array = new int [3];//动态初始化
System.out.println(array);//地址值[I@5acf9800
System.out.println(array[0]);//默认值0
System.out.println(array[1]);//默认值0
System.out.println(array[2]);//默认值0
System.out.println("========");
//改变数组当中的元素内容
array[1] = 10;
array[2]=20;
System.out.println(array);//地址值[I@5acf9800
System.out.println(array[0]);//默认值0
System.out.println(array[1]);//10
System.out.println(array[2]);//20
}
}
以上代码在内存图当中的传递调用如图
九、两个数组的内存图
2021、9、4更新
笔记:
定义了两个数组,那数组与数组之间不产生联系,各玩各的。
下列代码再内存当中的划分运行如图。
public class Demo07ArrayTwo {
public static void main(String[] args) {//方法区,后进栈
int [] arrayA/*栈*/ = new int [3];
System.out.println(arrayA);
System.out.println(arrayA[0]);
System.out.println(arrayA[1]);
System.out.println(arrayA[2]);//堆
System.out.println("========");
arrayA[1] = 10;//赋值数字10根据名称找到堆当中对应元素,再赋值交给
arrayA[2]=20;
System.out.println(arrayA);
System.out.println(arrayA[0]);
System.out.println(arrayA[1]);//10
System.out.println(arrayA[2]);//20
System.out.println("========");
int [] arrayB = new int [3];//地址值与arrayA不一样
System.out.println(arrayB);
System.out.println(arrayB[0]);
System.out.println(arrayB[1]);
System.out.println(arrayB[2]);
System.out.println("========");
arrayB[1] = 100;
arrayB[2]=200;
System.out.println(arrayB);
System.out.println(arrayB[0]);
System.out.println(arrayB[1]);//100
System.out.println(arrayB[2]);//200
System.out.println("========");
}
}
十、访问数组元素进行获取
2021、9、4更新
笔记:
1.将arrayA赋值交给arrayB,二者就是引用关系。二者共用一个堆。
2.拓展:在arrayB重新赋值1、2号元素后,再打印arrayA得到的是arrayB赋值1、2号元素后的数值。
/*
改一行代码,二者的运行结果完全不同
*/
public class Demo08ArraySame {
public static void main(String[] args) {//方法区,后进栈
int [] arrayA/*栈*/ = new int [3];
System.out.println(arrayA);
System.out.println(arrayA[0]);
System.out.println(arrayA[1]);
System.out.println(arrayA[2]);//堆
System.out.println("========");
arrayA[1] = 10;//赋值数字10根据名称找到堆当中对应元素,再赋值交给
arrayA[2]=20;
System.out.println(arrayA);
System.out.println(arrayA[0]);
System.out.println(arrayA[1]);//10
System.out.println(arrayA[2]);//20
System.out.println("========");
//arrayA与arrayB构引用关系,B引用A。
//将arrayA数组的地址值,赋值交给arrayB数组
//int [] arrayB = new int [3];//原代码
int [] arrayB = arrayA;//更改的代码
System.out.println(arrayB);
System.out.println(arrayB[0]);
System.out.println(arrayB[1]);//10
System.out.println(arrayB[2]);//20
System.out.println("========");
arrayB[1] = 100;
arrayB[2]=200;
System.out.println(arrayB);
System.out.println(arrayB[0]);
System.out.println(arrayB[1]);//100
System.out.println(arrayB[2]);//200
System.out.println("========");
//扩展,如果再打印arrayA,结果是
System.out.println(arrayA);
System.out.println(arrayA[0]);
System.out.println(arrayA[1]);//100
System.out.println(arrayA[2]);//200
System.out.println("========");
}
}
十一、常见问题 数组索引越界异常
2021、9、4更新
笔记:
1.数组的索引编号从0开始,一直到”数组长度-1“为止。
2.数组索引越界异常:指访问超出数组长度的索引编号。
/*
复习:
数组的索引编号从0开始,一直到"数组的长度-1"为止。
如果访问数组元素的时候,索引编号并不存在,那么将会发生
数组索引越界异常
ArrayIndexOutfboundsException
原因:索引编号超出数组长度
解决:修改成为存在的正确索引编号
*/
public class Demo09arrayIndex {
public static void main(String[] args) {
int [] array = {15,25,35};//静态初始化省略格式
System.out.println(array[0]);//15
System.out.println(array[1]);//25
System.out.println(array[2]);//35
//错误写法
//并不存在3号元素,所以发生异常
// 如果访问数组元素的时候,索引编号并不存在,那么将会发生
// 数组索引越界异常
System.out.println(array[3]);//Exceptiony异常
System.out.println(array[4]);//索引3、索引4都是不存在的索引
}
}
十二、常见问题 数组空指针异常
2021、9、4更新
笔记:
1.空指针:数组没有进行new创建,只赋值了一个null。
2.引用数据类型都可以赋值null,但是代表什么都没有。
/*
所有的引用类型变量,都可以赋值为一个null值。但是代表什么都没有
数组必须进行new初始化才能使用其中元素。
如果只是赋值了一个null,没有进行new创建,
那么将会发生,
空指针异常:NullPointerException
原因:忘了 new
解决:补上new
*/
public class Demo10ArrayNull {
public static void main(String[] args) {
// int [] array;
// array = new int[3];//加入忘记写此段代码直接打印数组
// System.out.println(array[0]);//错误,没new就没有创建数组
// 如果只是赋值了一个null,没有进行new创建,
// 那么将会发生,
// 空指针异常
// int [] array = null;
// System.out.println(array[0]);//空指针异常
int [] array;
array = new int[3];//补上一个new
System.out.println(array[0]);//0
}
}
十三、获取数组长度
2021、9、6更新
笔记:
注意:重新定义数组长度与变量赋值一样,虽名称未变,但其实际内容已经发生改变,不再与之前定义一样,如下。
2.获取静态数组长度标准格式
数组名称.length;
/*
如何获取数组的长度,格式:
数组名称.length
这将会得到一个int数字,代表数组的长度。
注意:
数组一旦创建,程序运行期间,长度不可改变。
*/
public class Demo11ArrayLength {
public static void main(String[] args) {
int [] arrayA = new int[3];//动态初始化
int [] arrayB = new int []{10,20,30,40,50,3,5,6,78,99,7,4,3,43,6,5,67,7,7,8,9,0,0,};//静态初始化
//获取静态初始化数组长度
//打印输出
System.out.println(arrayB.length);//23
//赋值获取
int len = arrayB.length;
System.out.println(len);//23
// arrayB.length;//不能单独调用,报错
System.out.println("========");
int [] arrayC = new int [3];//arrayC只是一个数组的名字,实质不代表数组,所以arrayC[3]和array[5]不是同一个数组
System.out.println(arrayC.length);//3
arrayC = new int[5];//重新赋值数组
System.out.println(arrayC.length);//5
}
}
十四、数组的遍历输出
2021、9、6更新
笔记:
1.巧用之前学过的知识,for循环。
2.数组名称.fori
/*
遍历数组:
说的就是就是对数组当中的每一个元素进行逐一、挨个儿处理,默认的处理方式就是打印输出。
*/
public class Demo12Array {
public static void main(String[] args) {
int[] array = new int []{14,23,45,32,64,67,41};
//首先使用原始方式
System.out.println(array[0]);//14
System.out.println(array[1]);//23
System.out.println(array[2]);//45
System.out.println(array[3]);//32
System.out.println(array[4]);//64
System.out.println(array[5]);//67
System.out.println(array[6]);//41
System.out.println("=========");
//使用循环,次数其实就是数组长度
for (int i = 0; i < 7; i++) {
System.out.println(array[i]);
}
System.out.println("========");
//再变形
//遍历数组
for (int i = 0; i < array.length; i++) {//数组名称.fori
System.out.println(array[i]);
}
}
}
十五、求出数组当中的最值
2021、9、7更新
笔记:
在数组当中灵活运用之前学的循环,以及if语句。
/*
题目:
打印输出数组当中的最大值
拓展:
输出但因数组当中的最小值
*/
public class Demo13ArrayMax {
public static void main(String[] args) {
int [] array = new int[]{10,20,30,-20,44,55,37,34,79,85,35,80,94,346,6,73,53,999};
//输出打印数组的最大值
int max=array[0];//比武擂台
for (int i = 1; i < array.length; i++) {
//如果当前元素比max更大,则换人
if (array[i]>max){
max=array[i];
}
// System.out.println(“最大值是”+max);//错误写法,将打印输出语句放在了for循环之内,导致每一次对比后都在打印输出。
}
System.out.println(“最大值是”+max);
//拓展
//最小值
int min = array[0];
for (int i = 0; i < array.length; i++) {
// min = array[0];//错误写法,min写在了方法里面,导致每一次都是循环都是以0号元素进行对比
if(array[i]<min){
min=array[i];
// minarray[i];//错误写法,min是变量,直接使用等于会报错
}
}
System.out.println(“数组的最小值为”+min);
}
}
十六、数组元素反转
2021、9、7更新
笔记:
这一章节比较难,建议反复观看。
/*
数组元素的反转:
例:
本来的样子[1,2,3,4,5]
反转后的样子[5,4,3,2,1]
题目要求:
不能使用新数组,就用原来唯一一个数组。
解析:
1.数组元素的反转其实就是对称位置的元素交换
2.通常遍历数组用的是一个索引,
int i=0;
现在表示对称位置需要两个索引
3.如何交换两个变量的值?
定义第三个变量用于倒手
int min = array[0];
int max = array.length-1;
int temp =min;
min=max;
max=temp;
4.什么时候停止交换
当min>=max时.
min<max时进行交换。
*/
public class Demo14ArrayReverse {
public static void main(String[] args) {
int [] array= new int[]{10,20,30,40,50,60,70,89};
//遍历打印数组本来的样子
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println("========");
//反转数组
/*
分析:
初始化语句:int min=0,max=array.length-1
条件判断:min<max;
条件判断:min++,max--
循环体:用第三个变量倒手
*/
for(int min=0,max=array.length-1 ;min<max;min++,max--){//注意定义max的时候不要再用数据类型int
int temp=array[min];
array[min]=array[max];
array[max]=temp;
}
//再次遍历打印数组
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
十七、数组作为方法传递
2021、9、8更新
笔记:此章节重点复习,掌握
/*
用数组作为方法的参数
对重复性代码,可以用循环。
也可以将其定义为一个方法,想什么时候用就什么时候用。
数组可以作为方法的参数。
当方法调用的时候,向方法的小括号进行传参printArray(array);传递进去的其实是数组的地址值。
*/
public class Demo15ArrayParam {
public static void main(String[] args) {
int[] array = new int[]{10, 20, 30, 40};
System.out.println(array);//地址值
printArray(array);// printArray( ),调用一个方法
//传递进去的就是array当中保存的地址值
System.out.println("======AAAAAA======");
printArray(array);
System.out.println("======BBBBBB======");
printArray(array);
System.out.println("======CCCCCC=====");
}
/*
三要素:
返回值类型:只是进行打印而已,不需要计算,也没有结果,用void
方法名称:printArray
参数列表:必须给我数组,我才能打印其中元素。int [] array
注意:任何数据类型都可以作为方法的参数
*/
public static void printArray(int [] array/*任何数据类型都可以作为方法的参数*/){
//注意上一段代码(int [] array),这只代表定义一个数组,new后面才是创建数组
System.out.println("printArray方法收到的参数是:");
System.out.println(array);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
十八、数组作为方法返回
2021、9、8更新
笔记:此章节重点复习,掌握
/*
一个方法可以有0、1多个参数;但是只能有0或者1个返回值,不能有多个返回值。
如果希望一个方法当中产生了多个结果数据进行返回,怎么办?
解决方法:使用一个数组作为返回值类型即可。
任何数据类型都能作为方法的参数类型,或者返回值类型。
数组作为方法的参数,传递进去的其实是数组的地址值
数组作为方法的返回值,返回的其实也是数组的地址值
*/
public class Demo16ArrayReturn {
public static void main(String[] args) {
//赋值调用
int [] result =calcuLate(10,20,30);[]这代表一个数组
System.out.print("总数:");
System.out.println(result[0]);
System.out.print("平均数:");
System.out.println(result[1]);
}
public static int[]/*数组的返回值类型*/ calcuLate(int a,int b,int c){//[]这代表一个数组
int sum = a+b+c;//求和
int avg = sum/3;//求平均数
//希望两个结果都返回
//需要一个数组,数组可以保存多个数据
//return sum,avg;//错误写法,多个返回值
//写法一,动态初始化
int [] array = new int [2];//创建一个数组
array[0]=sum;
array[1]=avg;
// //写法二,静态初始化
// int [] array={sum,avg};//静态初始化也可以使用变量
return array;
}
}
心得体会
2021、9、8更新
笔记:
本章节主要学习数组相关知识,对于后两个章节,逻辑性比较强,建议反复学习观看!加油,为明天而努力 。 2021、9、1