一:数组介绍
什么是数组?
数组就是一种容器,可以用来存储同种数据类型的多个值
数组:是一种容器,可以用户来存储同种类型的多个值
数组容器在存储数据的时候,需要结合隐式转换考虑
列如:int类型的数组容器(byte\short\int ) Boolean跟double不行
①:数组的定义
格式 一:数组类型[] 数组名
范例:int[] array
格式二:数据类型 数组名[]
范例: int array[]
②:数组的初始化
静态初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器的过程
完整格式: 数组类型[] 数组名 = new 数据类型[] {元素1,元素2,元素3......}
简化格式: 数据类型[] 数组名 = {元素1,元素2,元素3........};
范例: int [] array = new int [] {1,2,3,4,5};
范例:double[] array2 = new double[] {11.3,22.2,33.3};
public class ArrayDemo01 {
public static void main(String[] args) {
//定义五个学生成绩
int[] array = new int[]{11,22,33,44,55};
int[] array1 = {11,22,33,44,55};
//定义三个学生的姓名
String[] array2 = new String[]{"zhangsan","lisi","wangwu"};
String[] array3 = {"zhangsan","lisi","wangwu"};
//定义数组存储学生的身高
double[] array4 = new double[]{1.92,1.65,1.82,1.75};
double[] array5 = {1.92,1.65,1.82,1.75}; //[D@1b6d3586
}
}
③:数组地址访问与解释
[D@1b6d3586
D:代表的是里面的数据类型
@:表示一个间隔符号(固定的)
1b6d3586:是真正的地址值(16进制的数值)
格式:数组名 [索引]
索引也叫下标,角标
索引的特点由0开始,逐个+1开始,连续不断
④:数组的遍历跟练习
public class ArrayDemo02 {
public static void main(String[] args) {
//定义一个数组
int[] array = {1,2,3,4,5};
//获取数组里面所有的格式
//快捷生成 数组名称.fori
for (int i = 0; i < array.length; i++) {
//开始条件是从0开始的
//数组的结束条件是 数组的长度-1 结束的
System.out.println(array[i]); // 1,2,3,4,5
}
//查看数组的长度
//调用方式 数组的名称.length
System.out.println(array.length); // 5
}
}
//Practice01
public class Practice01 {
public static void main(String[] args) {
//定义一个数组,存1,2,3,4,5
//遍历数组里面的每一个数,然后求和
int[] arr = {1,2,3,4,5};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("这个数组的和是" + sum);
}
}
//Practice02
public class Practice02 {
public static void main(String[] args) {
//存储1,2,3,3,4,5,6,7,8,9,10
//遍历数组的元素,并统计数组里能被3整除的数据
int[] array = {1,2,3,4,5,6,7,8,9,10};
int sum = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] % 3 == 0){
System.out.println(array[i]);
sum ++;
}
}
System.out.println("能被三整除的数" + sum + "个");
}
}
//Practice03
public class Practice03 {
public static void main(String[] args) {
//存储1,2,3,4,5,6,7,8,9,10
//遍历数组的元素
//如果是偶数,则之前的数字缩减二分之
//如果是奇数,则放大两倍
int[] array = {1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 ==0){
array[i] = array[i] / 2;
}else {
array[i] = array[i] * 2;
}
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
⑤:数组的动态初始化和常见问题
数组动态初始化
动态初始化:初始化时只指定数组的长度,由系统为数组分配 初始值
格式: 数组类型【】 数组名称 = new 数组类型【数组长度】;
数组默认初始化规律
整数类型:默认初始化值为 0
小数类型:默认初始化值为 0.0
字符类型:默认初始化值为 '/u0000'
布尔类型:默认初始化值为 false
引用类型:默认初始化值为 null
动态初始化根静态初始化数组的区别
动态初始化:手动指定长度,由系统给出默认初始化值
只明确元素的个数,不确定具体数值,推荐使用动态初始化
eg:举例:使用容器来存储五个整数
->int[] array = {?,?,?,?,?};
->int[] array = new int[5s];
静态初始化:手动指定元素,系统会根据元素的个数,计算出数组的长度
需求中明确了具体要操作的数据,直接静态初始化即可
eg: 举例 将全班的学生成绩存入 11 , 22 ,33
int [] array = {11,22,33};
数组的常见问题
最小索引是0
最大索引:数组的长度 - 1
public class ArrayDemo04 {
public static void main(String[] args) {
int[] array ={1,2,3,4,5};
System.out.println(array[0]); // 1
System.out.println(array[10]); //会报错,报错信息为
}
}
//报错信息为
异常在main方法里面,数组的索引超出范围异常 ,数组索引10已经超出范围为5的索引
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: index 10 out of bounds for length 5
出现在com.fengjiasan.com.arraydemo这个包里面的ArrayDemo04这个类里面的main方法的第七行
at com.fengjiansan.com.arraydemo.ArrayDemo04.main(ArrayDemo04.java:7)
索引越界异常
①:访问不存在的索引
②:避免索引的范围
数组的常见操作
求最值
public class Practice04 {
public static void main(String[] args) {
/*
已知,数组元素为{33,5,22,44,45}请找出最大之,并打印
为什么要记录为arrayt[0],而不是直接为0,这样会让数组最大直接为0,并且如果求负数,很难得到里面的数值
循环的开始条件一定是0吗?
循环的开始条件为0,那么第一次循环的时候是跟自己比了一下,对结果没有任何影响,但是效率偏低
为了提高效率,减少循环次数,循环开始条件可以写1
*/
int[] array = {33,5,22,44,45};
//先定义0索引位置上的数最大
//如果是求最小值,反过来就可以了
int max = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i] > max){
max = array[i];
}
}
System.out.println("最大数是"+max); //45
}
}
求和
import java.util.Random;
public class Practice05 {
public static void main(String[] args) {
/*
需求:生成10个1~100之间的随机数存入数组
1)求出所有数据的和
2)求出所有数的平均数
3)统计多少个数比平均值小
*/
int[] array = new int[10];
Random random = new Random();
for (int i = 0; i < array.length; i++) {
//每循环一次都会生成随机数
int number = random.nextInt(100) + 1;
//把生成的随机放进数组
array[i] = number;
}
//定义求和变量
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
System.out.println("程序中所有数据的和为:" +sum);
// 2)求出所有数的平均数
int avg = sum / array.length;
System.out.println("数组中的平均数是:" + avg);
//3)统计多少个数比平均值小
int count = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] <avg){
count++;
}
}
System.out.println("数组中一共有:" + count +"个比平均数小");
//遍历数组验证答案
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}
交换数据
public class Practice06 {
public static void main(String[] args) {
/*
需求:定义一个数组,存入1,2,3,4,5按照要求更换索引的位置
交换前:1,2,3,4,5
交换后:5,2,3,4,1
*/
int[] array = {1,2,3,4,5};
//第一种方法
//将0索引位置上的数根最大索引位置互换
//用第三方变量交换
int temp = array[0];
array[0] = array[4];
array[4] = temp;
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " "); // 5 2 3 4 1
}
System.out.println(); //用于换行
//第二种方式,直接倒序,补考考虑其他位置上的数据
int[] array1 = {1,2,3,4,5};
for (int i = 0,j = array1.length - 1; i < j; i++,j--) {
//交换变量i根变量j
int temp1 = array1[i];
array1[i] = array1[j];
array1[j] = temp1;
}
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " "); // 5 4 3 2 1
}
}
}
打乱数据
import java.util.Random;
public class Practice07 {
public static void main(String[] args) {
/*
需求:定义一个数组,存入1~5,要求打乱数组中所有数据的顺序
*/
int[] array = {1,2,3,4,5};
Random random = new Random();
//遍历数组,从0开始打乱顺序
for (int i = 0; i < array.length; i++) {
//生成随机所有
int randomIndex = random.nextInt(array.length);
int temp = array[i];
array[i] = array[randomIndex];
array[randomIndex] = temp;
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i] + " ");
}
}
}
⑥:Java内存分配
栈、堆、方法区、本地方法栈、寄存器
注意:从jdk8开始,取消方法区,新增元空间,把原来的方法区的多种功能进行拆分,有的功能加入了堆中,有的功能放进了元空间
栈:方法运行时使用的内存,比如main方法,进入方法栈中执行
堆:存储对象或者数组,new来创建的,都存储在堆中
方法区:存储可以运行class文件
本地方法栈:jvm在使用操作系统功能的时候使用,与开发无关
寄存器:给cpu使用,与开发无关
public static void main(String[] args){
int a = 10;
int b = 20;
int c = a + b;
sout(c);
}
数组的内存简单的图解