文章目录
一、数组的概述和静态初始化
1. 数组
⭐数组是一种容器,可以用来存储同种数据类型的多个值
① 数组容器在存储数据的时候,需要结合隐式转换考虑
② 例如:int类型的数组容器(byte short int)
③ 例如:double类型的数组容器(byte short int long float double)
④ 建议:容器的类型,和存储的数据类型保持一致
2. 定义
① 数据类型[] 数组名
int [] array
② 数据类型 数组名[]
int array[]
3. 数组的静态初始化
① 初始化:就是在内存中,为数组开辟空间,并将数据存入容器的过程
② 完整格式:数据类型[] 数组名 = new 数据类型[] {元素1, 元素2, 元素3……}
③ 范例:int[] array = new int[]{11, 22, 33};
④ 范例:double[] array2 = new double[]{11.1, 22.2, 33.3};
⑤ 简化格式:数据类型[] 数组名 = {元素1, 元素2, 元素3……}
4. 样例
package com.itheima.arraydemo;
public class ArrayDemo1{
public static void main(String[] args){
//格式:
//静态初始化
//完整格式:
//数据类型[]数组名 = new 数据类型[]{元素1, 元素2……}
//简化格式:
//数据类型[]数组名 = {元素1, 元素2……}
//需求1:定义数组存储5个学生的年龄
int[] arr1 = new int[]{
11,12,13,14,15};
int[] arr2 = {
11,12,13,14};
//需求2:定义数组存储3个学生的姓名
String[] arr3 = new String[]{
"zhangsan","lisi","wangwu"};
String[] arr4 = {
"zhangsan","lisi","wangwu"};
//需求3:定义数组存储4个学生的身高
double[] arr5 = double[]{
1.93,1.75,1.73,1.81};
double[] arr6 = {
1.93,1.75,1.73,1.81};
}
}
二、数组的地址值和元素访问
1. 数组的地址值
intp[] arr = {
1,2,3,4,5};
System.out.println(arr);//[I@6d03e736 地址值
package com.itheima.arraydemo;
public class ArrayDemo1{
public static void main(String[] args){
//格式:
//静态初始化
//完整格式:
//数据类型[]数组名 = new 数据类型[]{元素1, 元素2……}
//简化格式:
//数据类型[]数组名 = {元素1, 元素2……}
//需求1:定义数组存储5个学生的年龄
/*
int[] arr1 = new int[]{11,12,13,14,15};
int[] arr2 = {11,12,13,14};
//需求2:定义数组存储3个学生的姓名
String[] arr3 = new String[]{"zhangsan","lisi","wangwu"};
String[] arr4 = {"zhangsan","lisi","wangwu"};
//需求3:定义数组存储4个学生的身高
double[] arr5 = double[]{1.93,1.75,1.73,1.81};
*/
double[] arr6 = {
1.93,1.75,1.73,1.81};
System.out.println(arr6);//[D@776ec8df
//扩展:
//解释一下地址值的格式含义
//[:表示当前是一个数组
//D:表示当前数组里面的元素都是double类型的
//@:表示一个间隔符号(固定格式)
//776ec8df:才是数组真正的地址值(十六进制)
//平时我们习惯性的会把这个整体叫做数组的地址值
}
}
2. 数组元素的访问
① 格式:数组名[索引]
② 索引:也叫做下标,从零开始,不间断
③ 样例
package com.itheima.arraydemo;
public class ArrayDemo2{
public static void main(String[] args){
//利用索引对数组中的元素进行访问
//1.获取数组里面的元素
// 格式:数组名[索引]
int[] arr = {
1,2,3,4,5};
//获取数组中的第一个元素
//其实就是0索引上对应的元素
//int number = arr[0];
//System.out.println(number);//1
//获取数组中1索引上对应的数据,并直接打印出来
//System.out.println(arr[1]);//2
//2.把数据存储到数组当中
//格式:数组名[索引] = 具体数据/变量
//细节:一旦覆盖之后,原来的数据就不存在了
arr[0] = 100;
System.out.println(arr[0]);//100
}
}
三、数组的遍历和三道综合练习
1. 数组遍历
① 定义:将数组中所有的内容取出来,取出来之后可以(打印,求和,判断)
② 注意:遍历指的是取出数据的过程,不要局限的理解为,遍历就是打印!
2. 样例
package com.itheima.arraydemo;
public class ArrayDemo3{
public static void main(String[] args){
//1.定义数组
int[] arr = {
1,2,3,4,5};
//2.获取数组里面所有的元素
//格式:数组名[索引]
/*
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
*/
//利用循环改进代码
//开始条件:0
//结束条件:数组的长度 - 1(最大索引)
/*
for(int i = 0; i < 5; i++){
//i:0 1 2 3 4
System.out.println(arr[i]);
}
*/
//在Java中,关于数组的一个长度属性,length
//调用方式:数组名.length
//System.out.println(arr.length);
for(int i = 0; i < arr.length; i++){
//i:0 1 2 3 4
System.out.println(arr[i]);
}
}
}
3. 练习
package com.itheima.test;
public class ArrTest1{
public static void main(String[] args){
/*
定义一个数组,存储1,2,3,4,5
遍历数组得到每一个元素,求数组里面所有的数据和
*/
//分析:
//1.定义一个数组,并添加数据1,2,3,4,5
int[] arr = {
1,2,3,4,5};
//求和变量
int sum = 0;
//2.遍历数组得到每一个数据,累加求和
for(int i = 0; i < arr.length;i++){
//i 依次表示数组里面的每一个索引
//arr[i] 依次表示数组里面的每一个元素
sum = sum + arr[i];
}
//当循环结束之后,sum的值就是累加之后的结果
System.out.println(sum);
}
}
package com.itheima.test;
public class ArrTest2{
public static void main(String[] args){
/*
定义一个数组,存储1,2,3,4,5,6,7,8,9,10
遍历数组得到每一个元素,统计数组里面一共有多少个能被3整除的数字
*/
//分析:
//定义一个数组 存储1,2,3,4,5,6,7,8,910
int[] arr = {
1,2,3,4,5,6,7,8,9,10};
//定义一个变量,用来统计个数
int count = 0;
//2.遍历数组得到每一个元素
for(int i = 0; i < arr.length;i++){
//i 表示数组里面每一个索引
//arr[i] 表示数组里面的每一个元素
//3.判断当前的元素是否为3的倍数,如果是那么统计变量就需要自增一次
if(arr[i] % 3 == 0){
//System.out.println(arr[i]);
count++;
}
}
//当循环结束之后,就表示数组里面所有的数字都判断完毕了,直接打印count即可
System.out.println("数组中能被3整除的数字有"+count+"个");
}
}
package com.itheima.test;
public class ArrTest3{
public static void main(String[] args){
/*
定义一个数组,存储1,2,3,4,5,6,7,8,9,10
遍历数组得到每一个元素
要求:
1.如果是奇数,则当前数字扩大两倍
2.如果是偶数,则当前数字变成二分之一
*/
//分析:
//1.定义一个数组,存1,2,3,4,5,6,7,8,9,10
int[] arr = {
1,2,3,4,5,6,7,8,9,10};
//2.遍历数组得到每一个元素
for(int i = 0; i < arr.length; i++){
//i 依次表示数组里面的每一个索引
//arr[i] 依次表示数组里面的每一个元素
//3.对每一个元素进行判断
if(arr[i] % 2 == 0){
//偶数 变成二分之一
arr[i] = arr[i] / 2;
}else{
//奇数 扩大两倍
arr[i] = arr[i] * 2;
}
}
//遍历数组
//一个循环尽量只做一件事情
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
}
四、数组的动态初始化和常见问题
1. 数组动态初始化
① 动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
② 格式:数据类型[] 数组名 = new 数据类型[数组长度];
③ 范例:int[] arr = new int[3];
④ 样例
package com.itheima.arraydemo;
public class ArrayDemo4{
public static void main(String[] args){
/*
定义一个数组,用来存班级中50个学生的姓名
姓名未知,等学生报道后,再进行添加
*/
//格式:
//数据类型[] 数组名 = new 数据类型[数组长度];
//再创建的时候,由我们自己指定数组的长度,由虚拟机给出默认的初始化值
String[] arr = new String[50];
//添加学生
arr[0] = "zhangsan";
arr[1] = "lisi";
//获取
System.out.println(arr[0]);//zhangsan
System.out.println(arr[1]);//lisi
System.out.println(arr[2]);//打印出来的是默认初始化值
//数组默认初始化值的规律
//整数类型:默认初始化值0
//小数类型:默认初始化值0.0
//字符类型:默认初始化值'/u0000' 空格
//布尔类型:默认初始化值 false
//引用数据类型:默认初始化值 null
int [] arr2 = new int[3];
System.out.println(arr[0]);//0
System.out.println(arr[1]);//0
System.out.println(arr[2]);//0
}
}
2. 数组动态初始化和静态初始化的区别
① 动态初始化:手动指定数组的长度,由系统给出默认初始化值
只明确元素的个数,不明确具体数值,推荐使用动态初始化
② 静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组的长度
需求中已经明确了要操作的具体数据,直接静态初始化即可
3. 数组常见问题
① 当访问了数组中不存在的索引,就会引发索引越界异常
② 样例
package com.itheima.arraydemo;
public class ArrayDemo4{
public static void main(String[] args){
//1.定义一共数组
int[] arr = {
1,2,3,4,5};
//长度:5
//最小索引:0
//最大索引:4(数组的长度 - 1)
System.out.println(arr[2]);
//小结:
//索引越界异常
//原因:访问了不存在的索引
//避免:索引的范围
//最小索引:0
//最大索引:4(数组的长度 - 1)
}
}
五、数组练习1-求最值
package com.itheima.test;
public class ArrTest4{
public static void main(String[] args){
//定义数组求最大值:33,5,22,44,55
//扩展问题:
//1.根据求最大值问题的思路,自己改写一下求最小值
//2.为什么max要记录为arr[0],默认值不能为0吗
//不能写0
//max的初始化值一定要是数组中的值
//3.循环中开始条件一定是0吗
//循环的开始条件如果为0,那么第一次循环的时候是自己跟自己比了一下,对结果没有任何影响,但是效率偏低
//为了提高效率,减少一次循环的次数,循环开始条件可以写1
//1.定义数组用来存储5个值
int[] arr = {
33,5,22,44,55};
//2.定义一个变量max用来存储最大值
//临时认为0索引的数据是最大的
int max = arr[0];
//3.循环获取数组中的每一个元素
//拿着每一个元素跟max进行比较
for(int i = 0; i < arr.length; i++){
//i 索引 arr[i] 元素
if(arr[i] > max){
max = arr[i];
}
}
//当循环结束之后,max记录的就是数组中的最大值
System.out.println(max);//55
}
}
六、数组练习2-求和并统计个数
package com.itheima.test;
public class ArrTest5{
public static void main(String[] args){
/*
需求:生成10个1~100之间的随机数存入数组
1) 求出所有数据的和
2) 求所有数据的平均数
3) 统计有多少个数据比平均值小
*/
//分析:
//1.定义数组
int[] arr = new int[10];
//2.把随机数存入到数组当中
Random r = new Random();
for(int i = 0; i < arr.length; i++){
//每循环一次,就会生成一个新的随机数
int number = r.nextInt(100) + 1;
//把生成的随机数添加到数组当中
//数组名[索引] =数据
arr[i] = number;
}
//遍历数组
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
// 1) 求出所有数据的和
//定义求和变量
int sum = 0;
for(int i = 0; i < arr.length; i++){
//循环得到每一个元素
//并把元素累加到sum当中
sum = sum + arr[i];
}
System.out.println("数组中所有数据的和为:"+sum);
// 2) 求所有数据的平均值
int avg = sum / arr.length;
System.out.println("数组中平均数为:"+avg);
// 3) 统计有多少个数据比平均值小
int count = 0;
for(int i = 0; i < arr.length; i++){
if(arr[i] < avg){
count++;
}
}
//当循环结束之后,就表示我已经找到了所有比平均数小的数据
System.out.println("在数组中,一共有"+count+"个数据,比平均数小");
//遍历数组,验证答案
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i] + " ");
}
}
}
七、数组练习3-交换数据
package com.itheima.test;
public class ArrTest6{
public static void main(String[] args){
/*
需求:定义两个变量,交换两个变量记录的值
*/
int a = 10;
int b = 20;
/*
//把变量b的值,赋值给了变量a,那么变量a原来的值就被覆盖了
a = b;//a = 20 b =20
//把变量a的值,赋值给了b
b = a;//a = 20 b =20
//System.out.println(a);//20
*/
//定义一共临时的第三方变量
//把变量a的值,赋值给了temp
int temp = a;
//把变量b的值,赋值给了a,那么变量a原来记录的值就被覆盖了
a = b;
//就是把变量a原来的值赋值给了变量b
b = temp;
system.out.println(a);//20
system.out.println(b);//10
}
}
package com.itheima.test;
public class ArrTest7{
public static void main(String[] args){
/*
需求:定义一个数组,将数组中0索引和最大索引处的值进行交换
*/
//1.定义一个数组
int[] arr = {
1,2,3,4,5};
//2.将数组中0索引和最大索引处的值进行交换
//也是可以利用第三方变量进行交换
int temp = arr[0];
arr[0] = arr[4];
arr[4] = temp;
//3.遍历数组
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i] + " ");
}
}
}
package com.itheima.test;
public class ArrTest8{
public static void main(String[] args){
/*
需求:
定义一个数组,存入1,2,3,4,5,交换首尾索引对应的元素
交换前:1,2,3,4,5
交换后:5,4,3,2,1
*/
//1.定义数组存储数据
int[] arr = {
1,2,3,4,5};
//2.利用循环去交换数据
for(int i = 0,j = arr.length - 1; i < j; i++,j--){
//交换变量i和变量j指向的元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//当循环结束之后,那么数组中的数据就实现了头尾交换
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i] + " ");
}
}
}
八、数组练习4-打乱数据
package com.itheima.test;
public class ArrTest9{
public static void main(String[] args){
//需求:定义一个数组,存入1~5,要求打乱数组中所有数据的顺序
//难点:
//如何获取数组中的随机索引
/*
int[] arr = {1,2,3,4,5};
//索引范围:0 1 2 3 4
Random r = new Random();
int randomIndex = r.nextInt(arr.length);
System.out.println(randomIndex);
*/
//1.定义数组存储1~5
int[] arr = {
1,2,3,4,5};
Random r = new Random();
for(int i = 0; i < arr.length; i++){
//生成一个随机索引
int randomIndex = r.nextInt(arr.length);
//拿着随机索引指向的元素跟i指向的元素进行交换
int temp = arr[i];
arr[i] = arr[randomIndex];
arr[randomIndex] = temp;
}
//当循环结束之后,那么数组中所有的数据已经打乱顺序了
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i] + " ");
}
}
}
九、数组的内存图
1. Java的内存分配
① 栈:方法运行时使用的内存,比如main方法运行,进入方法栈中执行
② 堆:存储对象或者数组,new来创建的,都存储在堆内存
③ 方法区:存储可以运行的class文件
④ 本地方法栈:JVM在使用操作系统功能的时候使用,和我们开发无关
⑤ 寄存器:给CPU使用,和我们开发无关
注意:
从JDK8开始,取消方法区,新增元空间。把原来方法区的多种功能进行拆分,有的功能放到了堆中,有的功能放到了元空间中。
2. 数组的内存图
① 只要new出来的一定是在堆里面开辟了一个小空间
② 如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据
3. 两个数组指向同一个空间的内存图
当两个数组指向同一个小空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改之后的结果了