五、 java中数组
定义数组的两种方式
class myarray1 { public static void main(String[] args) { //1.如何定义一个数组 //1.1数组的声明 String[] names; int scores[]; //1.2初始化 //第一种:静态初始化:初始化数组与给数组元素赋值同时进行。 names = new String[]{"jeff","frank","xixi"}; //第二种:动态初始化:初始化数组与给数组元素赋值分开进行。 scores = new int[4]; //2.如何调用相应的数组元素:通过数组元素的下角标的方式来调用。 //下角标从0开始,到n -1 结束。其中n表示的数组的长度。 scores[0] = 87; scores[1] = 89; scores[3] = 98; //3.数组的长度:通过数组的length属性。 System.out.println(names.length);//3 System.out.println(scores.length);//4 //4.如何遍历数组元素 // System.out.println(names[0]); // System.out.println(names[1]); // System.out.println(names[2]); for(int i = 0;i < names.length;i++){ System.out.println(scores[i]); System.out.println(names[i]); } } }
运行结果
3 4 87 jeff 89 frank 0//未赋值为0 xixi
未赋值的数组结果会打印什么
public class weifuzhi { public static void main(String[] args) { // TODO Auto-generated method stub //对于基于基本数据类型的变量创建的数组:byte short int long float double char boolean //1.对于byte short int long 而言:创建数组以后,默认值为0 int[] scores = new int[4]; scores[0] = 89; scores[3] = 90; for(int i = 0;i < scores.length;i++){ System.out.println(scores[i]); } byte[] scores1 = new byte[4]; scores1[0] = 89; scores1[3] = 90; for(int i = 0;i < scores1.length;i++){ System.out.println(scores1[i]); } } }
运行结果:
89 0 0 90 89 0 0 90
public class weifuzhi { public static void main(String[] args) { //2.对于float double而言:默认值是0.0 float[] f = new float[3]; f[0] = 1.3f; for(int i = 0;i < f.length;i++){ System.out.println(f[i]); } System.out.println(); } }
运行结果:
1.3 0.0 0.0
public class weifuzhi { public static void main(String[] args) { //3.对于char而言:默认为空格 char[] c = new char[3]; c[0] = 'a'; for(int i = 0;i < c.length;i++){ System.out.println(c[i]); } System.out.println(); } }
运行结果:
a
public class weifuzhi { public static void main(String[] args) { //4.对于boolean而言:默认为false boolean[] b = new boolean[3]; for(int i = 0;i < b.length;i++){ System.out.println(b[i]); } } }
运行结果:
false false false
public class weifuzhi { public static void main(String[] args) { //5.对于引用类型的变量构成的数组而言:默认初始化值为null。以String为例 String[] strs = new String[3]; strs[0] = "aa"; strs[1] = "bb"; //遍历数组的元素 for(int i = 0;i < strs.length;i++){ System.out.println(strs[i]); } System.out.println(); } }
运行结果:
aa bb null
那么,数组未定义和已定义在内存中是如何表现的呢。
借一张图,上图为内存结构的抽象图,在栈中存放局部变量和堆中变量实际引用的值的内存地址。堆中存放new开辟的内存空间及空间存放的值。
数组的生成
比如现在我们定义一个int[] scores = new int[4],这里做了两步操作,先在栈中生成局部变量scores,再在堆中开辟一块4个int大小的内存空间,在栈中将定义变量scores指向开辟的内存的起始地址。int类型开辟内存默认值为0。接下来要将我们动态赋值的数值放入指定的堆空间中,未赋值部分就是默认值。
静态初始化的操作步骤与上述基本一致,也是有默认开辟相应类型默认值的步骤,然后将后面的赋值部分存入堆的内存空间。
当我们之前定义的数组长度不够用了该怎么办。
public class short_array { public static void main(String[] args) { // TODO Auto-generated method stub int[] i = new int[]{12, 13, 14}; int[] j = new int[10]; for(int k = 0; k<i.length; k++){ j[k] = i[k]; } j[3] = 15; j[4] = 16; for(int k = 0;k < j.length;k++){ System.out.println(j[k]); } } }
运行结果:
12 13 14 15 16 0 0 0 0 0
例题:1.(1)定义类Pritimive,在类中定义一个有3个元素的boolean类型的数组t作为其成员变量。数组元素未赋值。
定义类TestPritimive,在TestPritimive的main()方法中创建Pritimive对象d,输出其成员变量t的三个元素值。
(2)给对象d的成员变量t赋值为{true,true,true},并输出t的三个元素值。
public class array_class { public static void main(String[] args) { //创建Pritimive的对象d Pritimive d = new Pritimive(); //遍历d的数组元素 for(int i = 0;i < d.t.length;i++){ System.out.println(d.t[i]); } //给d的数组元素重新赋值 d.t[0] = true; d.t[1] = true; d.t[2] = true; for(int i = 0;i < d.t.length;i++){ System.out.println(d.t[i]); } } } class Pritimive{ boolean[] t = new boolean[3]; }
运行结果
false false false true true true
从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
{成绩>=最高分-10 等级为’A’
成绩>=最高分-20 等级为’B’
成绩>=最高分-30 等级为’C’
其余 等级为’D’}
import java.util.Scanner; public class students_scores { public static void main(String[] args) { // 创建scanner对象,键入学生个数 Scanner s = new Scanner(System.in); System.out.println("student人数"); int count = s.nextInt();//count用来计数 //根据键入人数创建数组 int[] scores = new int[count]; int maxScore = scores[0]; //一次键入学生成绩,赋给相应数组元素,并获取最高分 System.out.println("请输入第" + count + "个成绩:"); for(int i=0; i<scores.length;i++){ int score = s.nextInt(); scores[i] = score; if(scores[i]>maxScore){ maxScore = scores[i]; } } //遍历学生成绩的数组,并根据学生成绩与最高分的差值,赋予相应的等级,并输出 System.out.println("最高分为:" + maxScore); for(int i = 0;i < scores.length;i++){ char level; if(scores[i] >= maxScore - 10){ level = 'A'; }else if(scores[i] >= maxScore - 20){ level = 'B'; }else if(scores[i] >= maxScore - 30){ level = 'C'; }else{ level = 'D'; } System.out.println("student " + i + " score is " + scores[i] + " grade is " + level); } } }
二维数组
初始化
public class array2 { public static void main(String[] args) { // TODO Auto-generated method stub //定义一个二维数组 int[][] scores; //二维数组初始化 //静态初始化 scores= new int[][]{{1,2},{2,8},{6,6,6,6}}; String[][] names; //动态初始化1 names = new String[3][2]; //动态初始化2 names = new String[3][]; names[0] = new String[2]; names[1] = new String[1]; names[2] = new String[3]; } }
赋值操作
public class array2 { public static void main(String[] args) { //引用具体的某一个元素 int[][] fuzhi = new int[3][2]; fuzhi[0][1] = 12; fuzhi[2][1] = 33; } }
二维数组的长度
public class array2 { public static void main(String[] args) { // TODO Auto-generated method stub //定义一个二维数组 int[][] scores; //二维数组初始化 //静态初始化 scores= new int[][]{{1,2},{2,8},{6,6,6,6}}; String[][] names; //动态初始化1 names = new String[3][2]; //动态初始化2 names = new String[3][]; names[0] = new String[2]; names[1] = new String[1]; names[2] = new String[3]; //引用具体的某一个元素 int[][] fuzhi = new int[3][2]; fuzhi[0][1] = 12; fuzhi[2][1] = 33; //二维数组的长度:length属性 System.out.println(fuzhi.length);//3 //二维数组中元素的长度 System.out.println(fuzhi[0].length);//2 System.out.println(names.length);//3 System.out.println(names[2].length);//3 System.out.println(); } }
遍历二维数组
public class array2 { public static void main(String[] args) { // TODO Auto-generated method stub //定义一个二维数组 int[][] scores; //二维数组初始化 //静态初始化 scores= new int[][]{{1,2},{2,8},{6,6,6,6}}; //for循环遍历数组 for(int m = 0;m < scores.length;m++){//控制行数 for(int n = 0;n < scores[m].length;n++){ System.out.print(scores[m][n] + " "); } System.out.println(); } } }
二维数组的内存结构
二维数组的存储与一维数组并没有什么区别,只是在第一层的数组中存的是下一层数组的内存地址,真实存储数据的是在第二层数组中。
public class TestException { public static void main(String[] args) { //1.数组下标越界的异常:java.lang.ArrayIndexOutOfBoundsException int[] i = new int[10]; // i[0] = 90; // i[10] = 99; // for(int m = 0;m <= i.length;m++){ // System.out.println(i[m]); // } //2.空指针的异常:NullPointerException //第一种: // boolean[] b = new boolean[3]; // b = null; // System.out.println(b[0]); //第二种: // String[] str = new String[4]; // //str[3] = new String("AA");//str[3] = "AA"; // System.out.println(str[3].toString()); //第三种: int[][] j = new int[3][]; j[2][0] = 12; } }
声明:int[] x,y[]以下能允许通过编译的是:
首先分析,一维数组的定义方式为:int[]x或int x[]。
二维数组的定义方式为int[][] y 或int[] y[] 或 int y[][]。
本题定义的为int[] x与,int[] y[]。所以x是一维数组,y是二维数组。
public class yanghui { public static void main(String[] args) { // TODO Auto-generated method stub //每层的个数 int[][] yanghui = new int[10][]; for(int i =0;i<yanghui.length;i++){ yanghui[i] = new int[i+1]; } for(int i = 0;i<yanghui.length;i++){ for(int j = 0;j<yanghui[i].length;j++){ yanghui[i][0] = yanghui[i][i] = 1; if(i>1 && j>0 && j<i){ yanghui[i][j] = yanghui[i-1][j]+yanghui[i-1][j-1]; } } } //遍历二维数组 for(int i = 0;i < yanghui.length;i++){ for(int j = 0;j < yanghui[i].length;j++){ System.out.print(yanghui[i][j] + "\t"); } System.out.println(); } } }
java中的数组array1=array2,array2的栈存入array1的内存地址。
所以数组的复制不能这样操作
int[] arr1 = new int[arr.length]; for (int i = 0; i < arr1.length; i++) { arr1[i] = arr[i]; }
排序部分
public class array_sort { public static void main(String[] args) { // TODO Auto-generated method stub int[] array1 = new int[]{-2, 4, 32, 44, 0, 10, -5}; for(int i = 1;i<array1.length; i++){ for(int j=0;j<array1.length-i;j++){ if(array1[j]>array1[j+1]){ int temp = array1[j+1]; array1[j+1] = array1[j]; array1[j] = temp; } } } for(int m=0;m<array1.length; m++){ System.out.print(array1[m]+"\t"); } System.out.println(); } }
public class array_sort1 { public static void main(String[] args) { // TODO Auto-generated method stub //直接选择排序 int[] array1 = new int[]{-2, 4, 32, 44, 0, 10, -5}; for(int i = 0;i<array1.length; i++){ for(int j=i;j<array1.length;j++){ // int array_min=array1[i]; if(array1[i]>array1[j]){ int temp = array1[j]; array1[j] = array1[i]; array1[i] = temp; } } } for(int m=0;m<array1.length; m++){ System.out.print(array1[m]+"\t"); } System.out.println(); } }
//使用直接选择排序使数组元素从小到大排列 for(int i = 0; i < arr.length - 1; i++){ int t = i;//默认i处是最小的 for(int j = i;j < arr.length;j++){ //一旦在i后发现存在比其小的元素,就记录那个元素的下角标 if(arr[t] > arr[j]){ t = j; } } if(t != i){ int temp = arr[t]; arr[t] = arr[i]; arr[i] = temp; } }
附:
System.arraycopy的使用方法(使用它可以快速得到一个pop(某索引值)的新数组),java中没有pop()所以使用它可以快速的实现pop方法。
int[] a = new int[]{123, 31, 656, 12, 43, 5}; int[] b = new int[5]; System.arraycopy(a, 0, b, 0, 1);// [123, 0, 0, 0, 0] System.arraycopy(a, 0, b, 0, 2);// [123, 31, 0, 0, 0] System.arraycopy(a, 2, b, 1, 4);// [123,656,12,43, 5],前面已经修改了这个数组所以第一位不是0是,123了 System.out.println(Arrays.toString(b));