写在开头:今天我们将步入数组的学习
PS:本文是个人学习笔记,用于个人复习。文章内容引用尚学堂java300集教学。
数组
Ⅰ 数组的概念
-
数组的定义
数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先 后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标) 来访问它们。数组的四个基本特点:
- 长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素的类型必须是相同类型,不允许出现混合类型。
- 数组类型可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中存储的。 -
创建数组和初始化
(1)数组声明
声明格式type[] arr_name; //方式一(推荐使用这种方式) type[] arr_name[]; //方式二
注意事项
- 声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM 才分配空间,这时 才与长度有关
- 声明一个数组的时候并没有数组真正被创建
- 构造一个数组,必须指定长度。(2)初始化
静态初始化:
除了用 new 关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配 空间并赋值。int [ ] a = { 1, 2, 3 };// 静态初始化基本类型数组; Man[ ] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
动态初始化:
数组定义与为数组元素分配空间并赋值的操作分开进行。int[ ] a1 = new int[2];//动态初始化数组,先分配空间; a1[0]=1;//给数组元素赋值; a1[1]=2;//给数组元素赋值;
默认初始化:
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个 元素也被按照实例变量同样的方式被隐式初始化。int a2[ ] = new int[2]; // 默认值:0,0 boolean[ ] b = new boolean[2]; // 默认值:false,false String[ ] s = new String[2]; // 默认值:null, null
示例1:创建基本类型一维数组
public class Test { public static void main(String args[ ]) { int[ ] s = null; // 声明数组; s = new int[10]; // 给数组分配空间; for (int i = 0; i < 10; i++) { s[i] = i + 1;//给数组元素赋值; 数组是对象,数组中的元素就是对象的属性 System.out.print(s[i] + "\t"); } } }
运行结果:
内存分配图:
示例2:创建引用类型一维数组class Man{ private int age; private int id; public Man(int id,int age) { this.age = age; this.id = id; } public int getAge(){ return age; } public int getId(){ return id; } } public class AppMain { public static void main(String[ ] args) { Man[ ] mans; //声明引用类型数组; mans = new Man[10]; //给引用类型数组分配空间; Man m1 = new Man(1,11); Man m2 = new Man(2,22); mans[0]=m1;//给引用类型数组元素赋值; mans[1]=m2;//给引用类型数组元素赋值; System.out.println(mans[0].getId() + "\t" + mans[0].getAge() ); System.out.println(mans[1].getId() + "\t" + mans[1].getAge() ); } }
运行结果:
内存分配图:
Ⅱ 数组常见操作
-
数组的遍历
数组的遍历指的就是“通过循环遍历数组的所有元素”。数组元素下标的合法区间:[0, length-1]。我们可以通过下标来遍历数组中的元素,遍 历时可以读取元素的值或者修改元素的值。事实上我们之前的例子就有用到数组的遍历。public class Test { public static void main(String args[ ]) { int [] nums= new int[3]; //遍历初始化数组 for(int i=0; i<nums.length; i++){ nums[i] = i+1; } //遍历读取数组元素的值 System.out.println("普通遍历:"); for(int i=0; i<nums.length; i++){ System.out.print(nums[i] + "\t"); } } }
-
for-each循环
增强 for 循环 for-each 是 JDK1.5 新增加的功能,专门用于读取数组或集合中所有的元 素,即对数组进行遍历。//接上一部分代码 //for-each循环 System.out.println("\n增强循环遍历:"); for(int num: nums){ System.out.print(num + "\t"); }
运行结果:
注意点:
- for-each 增强 for 循环在遍历数组过程中不能修改数组中某元素的值。
- for-each 仅适用于遍历,不涉及有关索引(下标)的操作。 -
数组的拷贝
System 类里也包含了一个 static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以将 src 数组里的元素值赋给 dest 数组 的元素,其中 srcpos 指定从 src 数组的第几个元素开始赋值,length 参数指定将 src 数组 的多少个元素赋给 dest 数组的元素。public class Test { public static void main(String args[ ]) { String[] company1 = {"百度", "阿里", "腾讯"}; String[] company2 = new String[3]; System.arraycopy(company1,0,company2,0,company1.length); for(String company:company2){ System.out.print(company + "\t"); } } }
运行结果:
-
java.util.Arrarys类
JDK 提供的 java.util.Arrays 类,包含了常用的数组操作,方便我们日常开发。Arrays 类包含了:排序、查找、填充、打印内容等常见的操作。
- 使用Arrays类输出数组中的元素import java.util.Arrays; public class Test { public static void main(String args[ ]) { int[] nums = {1, 2, 5, 8, 0}; //此处的 Arrays.toString()方法是 Arrays 类的静态方法,不是前面讲的 Object 的 toString() 方法。 System.out.println(Arrays.toString((nums))); } }
运行结果:
- 使用Arrays类对数组元素进行排序
import java.util.Arrays; public class Test { public static void main(String args[ ]) { int[] nums = {1, 2, 5, 8, 0}; Arrays.sort(nums); System.out.println(Arrays.toString((nums))); } }
运行结果:
如果想对某个类的对象之间做比较,就需要实现 Comparable 接口。接口中只有一个方法 compareTo,这个方法定义了对象之间的比较规则。 依据这个“比较规则”,我们就能对 所有对象实现排序。
import java.util.Arrays; public class Test { public static void main(String args[ ]) { Person[] people = {new Person(2,"李四"), new Person(1,"张三"), new Person(3, "王五")}; System.out.println("排序前:" + Arrays.toString(people)); Arrays.sort(people); System.out.println("排序后:" + Arrays.toString(people)); } } class Person implements Comparable{ int id; String name; public Person(int id, String name){ this.id = id; this.name = name; } public String toString(){ return this.name; } /*方法中,将当前对象和 obj 这个对象进行比较,如果 大于返回 1, 等于返回 0, 小于返 回-1. (此处的 1 也可以是正整数,-1 也可以是负整数)。 compareTo 方法的代码比较固定 */ public int compareTo(Object o){ Person person = (Person)o; if(this.id < person.id){ return -1; } if(this.id > person.id){ return 1; } return 0; } }
运行结果:
- 使用Arrays类对数组进行填充
import java.util.Arrays; public class Test { public static void main(String args[ ]) { int[] nums = {1, 2, 5, 8, 0}; //将1到5索引的元素替换为0(左闭右开); Arrays.fill(nums, 1, 5, 0); System.out.println(Arrays.toString((nums))); } }
运行结果:
Ⅲ 多维数组
-
多维数组
多维数组可以看成以数组为元素的数组。可以有二维、三维、甚至更多维数组,但是实 际开发中用的非常少。最多到二维数组(学习容器后,我们一般使用容器,二维数组用的都很少)。下面通过几个例子来学习二维数组的声明,初始化以及长度获取。
- 二维数组的声明import java.util.Arrays; public class Test { public static void main(String args[ ]) { // Java中多维数组的声明和初始化应按从低维到高维的顺序进行 int[][] a = new int[3][]; a[0] = new int[3]; a[1] = new int[2]; a[2] = new int[4]; // int a1[ ][ ]=new int[ ][4];//非法 //没有进行静态/动态初始化,则二维数组进行默认初始化 System.out.println(Arrays.toString(a[0])); System.out.println(Arrays.toString(a[1])); System.out.println(Arrays.toString(a[2])); } }
运行结果:
- 二维数组的初始化
import java.util.Arrays; public class Test { public static void main(String args[ ]) { //静态初始化 int[][] a = {{ 1, 2, 3 }, { 3, 4 }, { 3, 5, 6, 7 }}; //打印二维数组a System.out.println("二维数组a:"); System.out.println(Arrays.toString(a[0])); System.out.println(Arrays.toString(a[1])); System.out.println(Arrays.toString(a[2])); System.out.println(); //动态初始化 int[][] b = new int[3][]; b[0] = new int[]{1, 2, 3}; b[1] = new int[]{3, 4}; b[2] = new int[]{3, 5, 6, 7}; //打印二维数组b System.out.println("二维数组b:"); System.out.println(Arrays.toString(a[0])); System.out.println(Arrays.toString(a[1])); System.out.println(Arrays.toString(a[2])); //获取数组长度 System.out.println("数组b第一维长度:" + b.length); System.out.println("数组b第二维第一个数组长度:" + b[0].length); } }
运行结果:
二维数组内存分配图:
-
数组存储表格数据
ID 姓名 年龄 职能 入职日期 1001 张三 18 律师 2019-9-9 1002 李四 28 程序员 2019-10-9 1003 王五 38 医生 2019-4-9 - 使用二维数组保存上述表格信息
import java.util.Arrays; public class Test { public static void main(String args[ ]) { //每一个一维数组代表一行数据 Object[] emp0 = {1001, "张三", 18, "律师", "2019-9-9"}; Object[] emp1 = {1002, "李四", 28, "程序员", "2019-10-9"}; Object[] emp2 = {1003, "王五", 38, "医生", "2019-4-9"}; Object[][] emps = new Object[3][]; emps[0] = emp0; emps[1] = emp1; emps[2] = emp2; //打印表格数据 System.out.println(Arrays.toString(emps[0])); System.out.println(Arrays.toString(emps[1])); System.out.println(Arrays.toString(emps[2])); } }
- 使用javabean和一维数组保存上述表格信息(重点)
import java.util.Arrays; public class Test { public static void main(String args[ ]) { Emp emp0 = new Emp(1001, "张三", 18, "律师", "2019-9-9"); Emp emp1 = new Emp(1002, "李四", 28, "程序员", "2019-10-9"); Emp emp2 = new Emp(1003, "王五", 38, "医生", "2019-4-9"); Emp[] emps = new Emp[3]; emps[0] = emp0; emps[1] = emp1; emps[2] = emp2; //遍历数据 for(int i=0; i<emps.length; i++){ System.out.println(emps[i]); } } } class Emp{ //属性 private int id; private String name; private int age; private String job; private String hiredate; //无参构造函数 public Emp() { } //有参构造函数 public Emp(int id, String name, int age, String job, String hiredate) { this.id = id; this.name = name; this.age = age; this.job = job; this.hiredate = hiredate; } @Override public String toString() { return getId() + "\t" + getName() + "\t" + getAge() + "\t" + getJob() + "\t" + getHiredate(); } //get/set 方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public String getHiredate() { return hiredate; } public void setHiredate(String hiredate) { this.hiredate = hiredate; } }
运行结果: