Java数组
数组是具有相同数据类型且按一定次序排列的一组变量的集合体。即用一个变量名表示一批数据。Java为数组在内存中分配一段连续的空间,这段空间中存储数据的个数是固定的,数组就是一个容器,用来存一批同种类型的数据的。
一维数组
数组的定义和访问
-
定义数组
-
数据类型 数组名[ ];
-
数据类型[ ] 数组名;(推荐)
-
-
静态初始化数组
数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3}; 简化为: 数据类型[] 变量名 = {元素1,元素2,元素3}; String[] names = {"11吖", "33六", "334四"...}; System.out.println(names[1])
-
首先,左边 int[] ages 表示定义了一个数组类型的变量,变量名叫ages
-
其次,右边 {12,24,36} 表示创建一个数组对象,你完全可以把它理解成一个能装数据的东西。这个对象在内存中会有一个地址值 [I@4c873330 ,每次创建一个数组对象都会有不用的地址值。
-
然后,把右边的地址值 [I@4c873330 赋值给左边的ages变量
-
所以,ages变量就可以通过地址值,找到数组这个东西
数组变量名中存储的是数组在内存中的地址,数组是一种引用数据类型
-
-
数组元素访问
//访问数组中的元素格式: //数组名可以找到数组对象的地址,再通过索引就可以定位到具体的元素了 数组名[索引]
String[] names = {"11吖", "33六", "334四"};//静态初始化 System.out.println(names);//得到的是数组在内存中的地址 System.out.println(names[0]);//数组名找到数组对象的地址通过索引定位到0这个位置的元素 // 下面代码没有3索引,会出现ArrayIndexOutOfBoundsException 索引越界异常 // System.out.println(arr[3]);
4.数组长度
//访问数组的元素个数:数组名.length System.out.println(names.length); //获取数组的最大索引:arr.length-1 System.out.println(names.length-1); //数组中没有数据时获取的索引为-1 int[] arr2 = {}; System.out.println(arr2.length - 1);
-
数组遍历
用for循环遍历数组(一直遍历到长度-1)
int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
// i的取值 = 0, 1, 2
System.out.println(ages[i]);
}
//练习题
//需求:某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门
//的总销售额
int[] arr={16,25,36,6,100};
int sum=0;
for(int i =0;i<arr.length;i++){
sum+=arr[i];
}
System.out.println("员工的销售额:"+sum);
2.1数组的动态初始化
数组名 = new 数组类型[数组长度];
定义数组和为数组元素分配内存,和并在一起写,例如:
String[] names = new string[5];
// 数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];//int[] arr其实是一个变量,他记录了数组对象的地址值,而且数组中的元素默认值是0。
//使用动态化初始化数组时,根据元素类型不同,默认值也有不同
数组元素类型 | 默认初始值 |
---|---|
byte,short,int,long | 0 |
float,double | 0.0 |
char | ‘\u0000’(空字符) |
boolean | false |
引用数据类型 | null |
//某歌唱比赛,需要开发一个系统:可以录入6名评委的打分,录入完毕后立即输出平
//均分做选手得分
public static void main(String[] args){
double[] score = new double[6];
Scanner sc= new Scanner(System.in);
for(int i = 1;i <= 6;i++){
System.out.println("请输入第"+i+"个评委的成绩:")
double score = sc.nextDouble();
score[i-1]=score;
}
double sum = 0;
double avg = 0;
for(int i = 0;i<score.length;i++){
System.out.println(score[i]);
sum+=score[i];
}
avg = sum/score.length;
System.out.println("选手的成绩是" + avg);
}
//使用数组实现斐波拉切数列
public static void main(String[] args){
//输入n输入前n个数存储到数组再输出
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字");
int number = sc.nextInt();
int[] feibo = new int[number];
if(number == 1){
feibo[0]=1;
}else if(number == 2){
feibo[0]==1;
feibo[i]==1;
}else{
//feibo:1 1 2 3
feibo[0] = 1;
feibo[1] = 1;
for(int i=3;i<=number;i++){
//循环遍历的是它的长度,也就是说输入的数字是它的数组长度,下面求的是它的对应索引的值
feibo[i-1]=feibo[i-3]+feibo[i-2];
}
}
for(int i=0;i<feibo.length;i++){
System.out.println(feibo[i]);
}
}
数组使用过程中可能出现的问题
int[] scores = {32,45,45,76};
System.out.println(scores[5]); // 下标越界
int[] ages = {32,43,444,32,'a'};//'a'是char类型可以自动转化为int输出
System.out.println(ages[4]); // 97
int[] ages1 = {32,43,444,32L};//32L长度大于int型直接是错的
ages1[2] = 100;
ages[2] = 100L;
System.out.println(ages1[3]); // 报错 32
-
如果在数组中保存的元素可以自动提升(自动类型转化)为数组自己的类型,那是可以保存的
-
数组下标越界
数组在计算机中的执行原理
-
方法区:字节码文件先加载到这里
-
栈:方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
-
堆:存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域
-
a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
int a=10;这里int a是一个基本类型变量存储的是一个数值
-
arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
这里的int[] arr是一个引用类型的变量,存储的是一个地址值
int[] arr = new int[]{4,5,6};
int[] arr1 = new int[]{11, 22, 33};
// 把int类型的数组变量arr1赋值给int类型的数组变量arr2
int[] arr2 = arr1;//把arr1记录的地址,再赋值给arr2
int[] arr3 = new int[]{11, 22, 33};
System.out.println(arr1); // 地址
System.out.println(arr2); // 地址 1 == 2 都一样
System.out.println(arr3); // 地址 3 不一样
arr2[1] = 99;//改了arr2里的值相当于改了arr1里的值
System.out.println(arr1[1]);//所以输出为99
arr2 = null; // 拿到的数组变量中存储的值是null
System.out.println(arr2);
//System.out.println(arr2[0]);
//System.out.println(arr2.length);
-
两个变量指向同一个数组时,两个变量记录的是同一个地址值。
-
当一个变量修改数组中的元素时,另一个变量去访问数组中的元素,元素已经被修改过了。
使用增强for循环遍历数组
JDK1.5及其之后的版本中提供了增强for循环语句,实现了Iterable接口的类都可以使用增强for循环进行元素的迭代。增强for循环的语法规则如下:
for (元素类型 变量名 : 要迭代的对象) {
System.out.println(变量名);
}
int[] arr = {15, 9000, 10000, 20000, 9500, -5};
for (int e : arr) {
System.out.printn(e);
}
for (int i = 0; i < arr.length; i ++) {
System.out.printn(arr[i]);
}
多维数组
二维数组
定义二维数组的语法规则如下:
数据类型[ ] [ ]数组名;
或者
数据类型 数组名[ ] [ ];
语法解析:
[ ] [ ] 表示二维数组,前面的[ ]表示第一维,后面的[ ]表示第二维。
[][][ ] [ ] 放在数组名的前面或后面都是正确的。
分配内存
int[][] arr = new int[3][4];
数组元素初始化
int[][] arr = new int[3][4]; // 动态初始化
arr[0][0] = 1;
int[][] arr1 = new int[][]{ // 静态初始化
{1, 2, 3},
{2, 3},
{3, 4, 5, 4}
};
二维数组的迭代
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
for (int i1 = 0; i1 < arr1[i].length; i1++) {
System.out.println(arr1[i][i1]);
}
}
for (int[] t : arr1) {
for (int a : t) {
System.out.println(a);
}
}
public static void main(String[] args) {
//编写一个给指定行数的杨辉三角形存储在二维数组并输出
Scanner sc = new Scanner(System.in);
System.out.println("请输入行数");
int i = sc.nextInt();
yanghui(i);
}
public static void yanghui(int number){
int[][] arr =new int[number][number];
for(int i=0;i< arr.length;i++){
for(int j=0;j<=i;j++){
if(j==0||j==i){
arr[i][j]=1;
}else{
arr[i][j]=arr[i-1][j]+arr[i-1][j-1];
}
}
}
for (int[] a:
arr) {
for (int aint:
a) {
if(aint!=0){
System.out.print(aint);
}
}
System.out.println();
}
}
数组工具类
Arrays类
方法 | 返回类型 | 说明 |
---|---|---|
equals(array1, array2) | boolean | 比较两个数组是否相等 |
sort(array) | void | 对数组array的元素进行排序 |
toString(array) | String | 将一个数组array转换成一个字符串 |
fill(array, val) | void | 把数组array的所有元素都赋值成val |
copyOf(array, length) | 与array数据类型一致 | 把数组array复制成一个长度为length的新数组 |
binarySearch(array, val) | int | 查询元素值val在数组array中的下标 |
compare(array1, array2) | int | 按字典顺序比较数组,前面的数组大,返回大于0的值,反之返回小于0的值 |
copyOfRange(arr, start, end) | 与array数据类型一致 | 将指定数组的指定范围复制到新数组中 |
fill(arr, start, end, val) | void | 将指定的值分配给指定数组的指定范围的每个元素 |
mismatch(array1, array2) | int | 查找并返回两个数组之间第一个不匹配的索引,如果未找到不匹配,则返回 -1 |
mismatch(array1, start1, end1, array2, start2, end2) | int | 查找并返回指定范围内两个数组之间第一个不匹配的相对索引,如果未找到不匹配,则返回 -1 |
- 比较两个数组是否相等
Arrays类的equals()方法用于比较两个数组是否相等。只有当两个数组长度相等,对应位置的元素也一一相等时,该方法返回true,否则返回false。
System.out.println(arr == arr1);
System.out.println(Arrays.equals(arr, arr1));
- 对数组元素进行升序排序
Arrays类的sort()方法对数组的元素进行升序排序
int[] arr = new int[]{12, 23, 34, 21, 22, 10};
int[] arr1 = new int[]{12, 23, 34, 21, 22, 10};
Arrays.sort(arr);
for (int i : arr) {
System.out.println(i);
}
- 将数组转换成字符串
Arrays类中提供了专门输出数组内容的toString()方法。该方法用于将一个数组转换成一个字符串。它按顺序把多个数组元素连在一起,多个数组元素之间使用英文逗号和空格隔开。利用这种方法可以很清楚地观察到各个数组元素的值。
int[] newArr = new int[5];
Arrays.fill(newArr, 5); System.out.println(Arrays.toString(newArr)); // [5, 5 , 5, 5, 5]
System.out.print("[");
- 将数组赋值成一个长度为设定值的新数组
System.arraycopy() 方法从指定的源数组复制一个数组,从指定位置开始,到目标数组的指定位置。该方法声明如下:
public static void arrcopy(Object src, int srcPos, Object dest, int destPos, int length)
src:这是源数组。
srcPos:这是源数组中的起始位置。
dest:这是目标数组。
destPos:这是目标数据中的起始位置。
length: 这是要复制的数组元素的数量。
- 数组组件的子序列从 src 引用的源数组复制到 dest 引用的目标数组。复制的组件数等于 length 参数。源数组中位置srcPos到srcPos + length - 1的元素被复制到目标数组的destPos 到 destPos + length - 1的位置。
public class Test3 {
public static void main(String[] args) {
//给定一个数组,请根据输入在数组的指定位置插入指定的值。
int[] arr = {1,9,7,0,19,13,22};
Scanner sc = new Scanner(System.in);
System.out.println("请输入想插入的位置");
int key = sc.nextInt();
System.out.println("请输入想插入的数字");
int number = sc.nextInt();
charu(arr,key,number);
}
public static void charu(int[] arr,int key,int number){
int[] newArr=new int[arr.length+1];
System.arraycopy(arr,0,newArr,0,key);
newArr[key]=number;
System.arraycopy(arr,key,newArr,key+1,newArr.length-(key+1));
for (int a:
newArr) {
System.out.println(a);
}
}
= sc.nextInt();
charu(arr,key,number);
}
public static void charu(int[] arr,int key,int number){
int[] newArr=new int[arr.length+1];
System.arraycopy(arr,0,newArr,0,key);
newArr[key]=number;
System.arraycopy(arr,key,newArr,key+1,newArr.length-(key+1));
for (int a:
newArr) {
System.out.println(a);
}
}