数组
1、数组介绍
数组:指的是一种容器,用来存储同种数据类型的多个值 数组容器在存储数据的时候,需要结合隐式转换 建议:容器的类型,和存储的数据类型保持一致
2、数组的定义与静态初始化
数组的定义:
/*
格式一(常用): 数据类型[] 数组名
int [] array
格式二:数据类型 数组名[]
int arry[]
*/数组的初始化:在内存中,为数据容器开辟空间,并将数据存入容器中的过程
/*
1、数组的静态初始化
完整格式:数据类型[] 数组名 = new 数组类型[] {元素1, 元素2,...};
举例:
int[] array = new int[]{11, 22, 33};
double[] array2 = new double[]{11.1, 22.2, 33.3};
简化:数据类型[] 数组名 = {元素1, 元素2,...};
举例:
int[] array = {11, 22, 33};
double[] array2 = {11.1, 22.2, 33.3};
注意:定义数组后,数组长度为元素个数,且长度就固定了
*/
public class ArrayDemo1 {
public static void main(String[] args) {
//完整格式:数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...};
//简化格式:数据类型[] 数组名 = {元素1, 元素2, 元素3, ...};
/*
// 需求1:定义数组,存储5个学生的年龄
int[] arr1 = new int[]{11, 12, 13, 14, 15};
int[] arr2 = {11, 12, 13, 14, 15};
System.out.println(arr2);
// 需求2:定义数组存储3个学生的姓名
String[] arr3 = new String[]{"张三", "李四", "王五"};
String[] arr4 = {"张三", "李四", "王五"};
System.out.println(arr4);
// 需求3:定义数组存储4个学生的身高
double[] arr5 = new doble[]{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 表示数组真正的地址值
}
}3、数组元素访问
数组的地址值:数组容器在内存中的地址值
int[] arr = new int[]{1, 2, 3, 4};
System.out.println(arr); // 输出的内容为数组的地址值数组元素访问:
/*
格式:数组名[索引];
索引:也叫做下标,角标
索引的特点:从0开始,逐个+1增长,连续不间断
*/
public class ArrayDemo2 {
public static void main(String[] args) {
/* 利用索引对数组中的元素进行访问
1、获取数组中的元素
格式:数组名[索引];
*/
int[] arr = new int[]{1, 2, 3, 4, 5};
// 先获取一个元素定义给一个变量再输出
int number = arr[0];
System.out.println(number);
//直接输出
System.out.println(arr[1]);
/*
2、把数据存储到数组中
格式: 数组名[索引] = 具体数据/变量;
注意:一旦写入,为覆盖操作,原来的数据将不存在
*/
arr[0] = 100;
System.out.println(arr[0]);
}
}4、数组遍历
获取数组中每一个元素(去除数组元素的整个过程)
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]); */
//利用循环改进代码-v1
/*
for (i = 0; i < 5; i++){
System.out.println(arr[i]);
}
*/
//利用循环改进代码-v2
/*
java中,关于数组的一个长度属性,length
调用方式:
数组名.length
*/
//System.out.println(arr.length);
for (i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
/* 扩展:idea中自动填充,实现数组的遍历
数组名.fori + 回车
*/
}
}4.1 练习-数组元素求和
public class ArrTest1 {
public static void main(String[] args){
/* 定义一个数组,存储1,2,3,4,5
遍历数组得到每一个元素,求数组中所有数据的和 */
int[] arr1 = new int[]{1, 2, 3, 4, 5}; // 定义数组
//循环求和
int sum = 0;
for (int i = 0; i < arr1.length; i++){
sum = sum + arr1[i];
}
System.out.println(sum); //输出求和结果
}
}4.2 练习-统计数组中部分数字个数-1
public class ArrTest2 {
public static void main(String[] args){
/* 定义一个数组,存储1, 2, 3, 4, 5,6, 7, 8, 9, 10
遍历数组得到每一个元素,统计数组中,一共有多少个能被3整除的数字 */
int[] arr1 = new int[]{1, 2, 3, 4, 5,6, 7, 8, 9, 10};
int count = 0;
for (int i = 0; i < arr1.length; i++){
/*
arr[i] 表示数组中每一个元素
i表示数组中每一个索引
*/
if (arr1[i] % 3 == 0){
System.out.println(arr1[i]);
count++;
}
}
System.out.println("能被3整除的数字有" + count + "个");
}
}4.3 练习-统计数组中部分数字个数-2
public class ArrTest3 {
public static void main(String[] args){
/*
定义一个数组,存储 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
遍历数组得到每一个元素
要求:
1、如果是奇数,则将当前数字扩大两倍
2、如果是偶数,则将当前数字变成二分之一
*/
//定义数组存储数据
int[] arr1 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//循环遍历每个元素
for (int i = 0; i < arr1.length; i++){
//偶数变成二分之一,奇数变成二倍
if (arr1[i] % 2 == 0 ){
arr1[i] = arr1[i] / 2; //arr1[i] /= 2;
} else {
arr1[i] = arr1[i] * 2; //arr1[i] *= 2;
}
}
//遍历数组(注意:一个循环只做一件事情)
for (int i = 0; i < arr1.length; i++){
System.out.println(arr1[i]);
}
}
}5、数组动态初始化
/*
动态初始化:初始化时只指定数组长度,有系统为数组分配初始值
格式:数据类型[] 数组名 = new 数据类型[数组长度];
范例:int[] arr = new int[3];
*/案例:
package com.yq.arraydemo;
public class ArrayDemo4 {
public static void main(String[] args){
/*
定义一个数组,用来存班级中50个学生的姓名
姓名位置:等学生报道之后,再进行添加
*/
/*
格式:
数据类型[] 数组名 = new 数据类型[数组的长度]
在创建的时候,由我们自己指定数组的长度,由虚拟机给出默认的初始化值
*/
String[] arr = new String[50];
//添加学生
arr[0] = "张三";
arr[1] = "李四";
//获取
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
/*
数组默认初始化值的规律
整数类型:默认初始化值 0
小数类型:默认初始化值 0.0
字符类型:默认初始化值 '\u0000' 表示空格
布尔类型:默认初始化值 false
引用数据类型:默认初始化值 null
*/
int[] arr2 = new int[3];
System.out.println(arr2[0]);
System.out.println(arr2[1]);
System.out.println(arr2[2]);
}
}数组动态初始化和静态初始化的区别:
/*
动态初始化:手动指定数组长度,由系统给出默认初始化值
只明确元素个数,不明确具体数值,推荐使用动态初始化
举例:使用数组容器存储键盘录入的5个整数
int[] arr = new int[5];
静态初始化:手动指定数组元素,系统会根据元素个数,计算数组的长度
举例:将全班的学生成绩存入数组中 11 , 22, 33
int[] arr = {11, 22 ,33};
*/6、数组内存图
Java内存分配
栈:方法运行时使用的内存,比如main方法运行,进入方法栈中执行
堆:存储对象或者数组,new来创建的,都存储在堆内存
方法区:存储可以运行的class文件
本地方法栈: JVM在使用操作系统功能的时候使用
寄存器:给CPU使用
总结:
1、只要是new出来的,一定是在堆里面开辟了一个小空间
2、如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据
两个数组指向同一个空间的内存图:
public static void main(String[] args){
int[] arr1 = {11, 22};
int[] arr2 = arr1;
System.out.println(arr1[0]);
System.out.println(arr2[0]);
arr2[0] = 33;
System.out.println(arr1[0]);
System.out.println(arr2[0]);
}
//总结:当两个数组指向同一个小空间时,其中一个数组小空间中的值发生了改变,那么其他数组再次访问时都是修改之后的结果了
7、数组常见问题
当访问了数组中不存在的索引,就会引发索引越界异常
package com.yq.arraydemo;
public class ArrayDemo5{
public static void main(String[] args){
//1.定义一个数组
int[] arr = {1,2,3,4,5,}; //数组长度为5;最小索引0;最大索引4
// System.out.println(arr[10]);
System.out.println(arr[2]);
/*
小结:索引越界异常
原因:访问了不存在的索引
避免:索引的范围
最小的索引:0
最大的索引:数组长度-1
*/
}
}8、数组常见操作
8.1 求最值
package com.yq.test;
public class ArrTest4{
public static void main(String[] args){
//定义数组求最大值: 33,5,22,44,55
//1、定义数组存数据
int[] arr = new int[]{33,5,22,44,55};
//2、定义变量max,用来存储最大值
int max = arr[0];
//3、循环求最大值
for (int i = 0; i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
}
System.out.println("最大值: " + max); //输出最大值
//4、拓展: 循环求最小值
int min = arr[0];
for (int i = 1; i < arr.length; i++){
if(arr[i] < min){
min = arr[i];
}
}
System.out.println("最小值: " + min); //输出最小值
/*
1、求最小值
2、为什么max记录为arr[0]
max的初始化值一定要是数组中的值
3、循环中开始条件一定是0吗?
for (int i = 0; i < arr.length; i++){}
循环从 i=0开始,会和自己比较一次
为了提高效率,减少一次循环次数,循环开始条件可以写1
*/
}
}8.2 求和
package com.yq.test;
import java.util.Random;
public class ArrTest5{
public static void main(String[] args){
/*
需求:生成10个1~100之间的随机数存入数组
1)求所有数据的和
2)求所有数据的平均数
3)统计由多少个数据比平均值小
*/
int[] arr1 = new int[10]; //动态初始化定义数组
Random r = new Random(); //赋值
for (int i = 0 ; i < arr1.length; i++){
int number = r.nextInt(100) + 1;
arr1[i] = number;
}
//遍历数组
for (int i = 0; i < arr1.length; i++){
System.out.print(arr1[i] + " ");
}
// 1)求所有数据的和
int sum = 0;
for (int i = 0; i < arr1.length; i++){
sum = sum + arr1[i];
}
System.out.println("");
System.out.println("所有数据的和: " + sum);
// 2)求所有数据的平均数
int avg = sum / arr1.length;
System.out.println("所有数据的平均数: " + avg);
// 3)统计有多少个数据比平均值小
int count = 0;
for (int i = 0; i < arr1.length; i++){
if (arr1[i] < avg){
count++;
}
}
System.out.println("比平均值小的个数: " + count);
}
}8.3 交换数据
package com.yq.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[] arr1 = new int[]{1, 12, 3, 24, 5,46,67,8,89};
int[] arr2 = new int[arr1.length];
for (int i = 0 ; i < arr2.length; i++){
arr2[i] = arr1[arr1.length - i - 1];
}
//遍历arr1 原数组
for (int i = 0 ; i < arr1.length; i++){
System.out.print(arr1[i] + " ");
}
System.out.println("");
//遍历arr2 交换后的数组
for (int i = 0 ; i < arr2.length; i++){
System.out.print(arr2[i] + " ");
}
System.out.println("");
//方法2:直接在数组中进行交换
int[] arr = new int[]{1, 2, 3, 4, 5};
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;
}
//遍历数组arr
for (int i = 0 ; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}8.4 打乱数据
package com.yq.test;
import java.util.Random;
public class ArrTest9{
public static void main(String[] args){
//需求:定义一个数组,存入1~5,要求打乱数组中所有数据的顺序
//1.定义数组存入数据
int[] arr = new int[]{1, 2, 3, 4, 5};
//2.循环遍历数组,从0索引开始打乱数据的顺序
Random r = new Random();
for (int i = 0 ; i < arr.length; i++){
int randomIndex = r.nextInt(arr.length);
int temp = arr[i];
arr[i] = arr[randomIndex];
arr[randomIndex] = temp;
}
//遍历打乱后的数组
for (int i = 0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
评论区