数组
一组数的容器
数组对每一个存入的数字都会自动编号,编号是从0开始的---下标
数组的定义格式
数据类型[] 变量名 = new 数据类型[数组大小或者元素的个数];---适用于知道元素个数而不知道具体数据的时候
int[] arr = new int[3];---表示这是一个能存储3个整数的数组
//数组的大小一旦定义好,不可以改变
arr[1] = 5;
int i = arr[1];
int i = 5;
int i; //声明
i = 5; //初始化---在程序中第一次给变量赋值
int[] arr;
arr = new int[5];---可以先声明再初始化
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3……};
int[] arr = new int[]{2,5,3,1,6};---在定义好之后,数组的初始元素已经一一赋值,数组的大小已经固定。
可以先声明再初始化吗?---可以
数据类型[] 数组名 = {元素1,.元素2,元素3……};
int[] arr = {2,3,1,6}; //在创建的时候动态的获取数组大小,然后才能分配内存空间
int[] arr;
arr = {1,5,3,7,4};---不可以---现在不知道数组的大小
内存
将内存分为了五块:栈内存、堆内存、方法区、本地方法栈、寄存器
栈内存
存储变量,执行代码块的。变量存储在栈内存中不会自动赋予初始值,变量使用完成之后立即移除出栈内存,释放空间
堆内存
存储对象,对象在堆内存中会自动赋予初始值。对象在使用完成之后,不会立即移除,而是在不定的某个时刻被回收。---初始值:byte/short/int---0,long---0L,float---0.0f
double---0.0,char--- ‘u0000’,boolean--false,其他的引用数据类型的初始值是null
ArrayIndexOutOfBoundsException---数组下标越界异常---编译没有问题---说明明语法没有问题---逻辑上或者事实上不符合--运行出错
NullPointorException---空指针异常---编译没有问题---对于null而言,不能做任何操作
int i = 5;
int j = i;
注意:对于基本类型而言,传值传的实际的数据;对于引用类型而言,传值传的是地址。
数组的应用
1. 获取数组中的元素---数组名[下标]
2. 获取数组的长度---数组名.length
3. 遍历数组---
for(int i = 0; i < arr.lenth; i++){}
for(int i : arr){}
//注意增强for循环不能改变数组中原来的元素
4. 获取数组中的最值---最大值
5. 对数组元素进行排序
冒泡排序
for(int i = 1 ; i < arr.length ; i++){ //控制轮数
for(int j = 1; j <= arr.length - i; j++){ //控制每轮的次数,以及下标
if(arr[j - 1] > arr[j] ){
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
}
选择排序
for(int i = 1; i < arr.length ; i++){ //控制轮数和起始下标
for(int j = i - 1; j < arr.length; j++){ //控制次数,后边那一位的下标的变化
if(arr[i - 1] > arr[j]){
int temp = arr[i - 1];
arr[i - 1] = arr[j];
arr[j] = temp;
}
}
}
快速排序、希尔排序、堆排序
import java.util.Arrays;
Arrays.sort(数组); //只能升序排列---从小到大
String s = Arrays.toString(arr);---将数组中的元素依次取出拼接成了一个字符串
6. 查找数组中元素
无序数组---for循环
有序数组---折半查找
7. 数组的反转
利用新的数组,也可以利用两个变量来同时操作数组的两端
8. 数组的扩容---数组的复制
System.arraycopy(要复制的数组,要复制的数组的起始位置,被复制到的数组,新数组中放置的起始位置,要复制的元素的个数);
System.arraycopy(arr,3,arr2,2,5);---从arr下标为3的位置开始复制,复制5个元素到arr2中,从arr2的下标为2的位置开始依次存放
数组 = Arrays.copyOf(数组,长度);---表面上看起来对数组的长度做了改变,实际上数组已经发生了变化,已经是一个新的数组
T[] arr2; //数据类型在Java底层动态获取的
arr2 = new T[长度]; //T---表示泛型
if(长度 >= 数组.length){
System.arraycopy(arr,0,arr2,0,arr.length);
} else {
Sysetem.arraycopy(arr,0,arr2,0,长度);
}
arr = arr2;
补充扩展:
1. int i = 1 / 0;---编译没有问题---运行---ArithmeticException---算术异常
在Java中小数允许除以0,结果是Infinity/NaN---Not a Number---NaN和任何值都不相等,即使是本身,也不相等。
2. 尽量减少使用小数作为控制条件----因为小数在计算机中不能够精确存储
3. strictfp---在函数执行过程中,小数是以80位二进制进行存储的,但是函数完成之后,依然使用double类型存储最终的结果---最终的结果依然是64位二进制小数
二维数组
是一组数组的容器---数组的数组
定义格式
数据类型[][] 数组名 = new 数据类型[二维数组的大小/二维数组中包含的一位数组的个数][所包含的一维数组的大小];
int[][] arr = new int[3][5];---表示这是一个包含3个一维数组的二维数组,每个一维数组由5个整数组成
int[] arr2 = arr[0];----获取的是一个一维数组
arr[0][3];---如果获取具体的元素,需要两个下标
数据类型[][] 数组名 = new 数据类型[二维数组的大小/包含的一维数组的个数][];
int[][] arr = new int[3][];---表示这个二维数组由3个整型的一维数组组成
arr[0][0] = 3; ---不可以---因为所包含的一维数组没有初始化
数据类型[][] 数组名 = {{元素1},{元素1,元素2} ……};
int[][] arr = {{1},{1,3},{2,4,3}};
arr[0][1] = 5;--不可以
面试题总结:对于数组int[] x,y[]均已初始化,下列选项正确的是:
A. y = x;
B. y[0] = x;
C. y[0][0] = x[0];
D. y[0] = x[0];
E. y = x[0];
注意:[]在变量名之前是紧跟数据类型的,那么后边跟的每个变量至少是一个一维数组;[]在变量名之后是仅属于当前变量的。
遍历一个二维数组---需要两个循环
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length ; j++){
arr[i][j];
}
}