目录
java_2">java的数组
数组的定义
数组是相同类型数据的有序集合。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问它们。数组的四个基本特点:
- 长度是确定的。数组一旦被创建,它的大小就是不可以改变的.。
- 其元素的类型必须是相同类型,不允许出现混合类型。
- 数组类型可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也是对象,数组中的元素相当于对象的属性!
创建数组和初始化
数组的声明方式(以一维数组为例)
java">type[] arr name; // 方式一
type arr_name[]; // 方式二
注意事项
- 声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM 才分配空间,这时才与长度有关。
- 声明一个数组的时候并没有数组真正被创建。
- 构造一个数组,必须指定长度。
案例
java">package com.itbaizhan;public class Test01 {public static void main(String[] args) {// 案例1int[] s; // 声明s = new int[10]; // 创建
// System.out.println(s[0]);
// System.out.println(s[1]);for (int i = 0; i < s.length; i++) {s[i] = 2 * i + 1; // 给数组元素赋值; 数组是对象,数组中的元素就是对象的属性
// System.out.println(s[i]);}// 案例2Man[] mans = new Man[10]; // 声明Man m1 = new Man(1, 11);Man m2 = new Man(2, 12);mans[0] = m1; // 赋值mans[1] = m2; // 赋值System.out.println(mans[0].getId());System.out.println(mans[0].getAge());System.out.println(mans[1].getId());System.out.println(mans[1].getAge());}
}class Man {private int age;private int id;public Man(int id, int age) {super();this.age = age;this.id = id;}public int getAge() {return age;}public int getId() {return id;}
}
数组的初始化
数组的初始化方式总共有三种:静态初始化、动态初始化、默认初始化
1. 静态初始化
除了用 new 关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。
【示例】数组的静态初始化
java">int[] a = {1, 2, 3};
Man[] mans = {new Man(1, 11), new Man(2, 12)};
2. 动态初始化
数组定义与为数组元素分配空间并赋值的操作分开进行,如下所示:
java">int[] a = new int[2]; //动态初始化数组,先分配空间,
a[0] = 1; //给数组元素赋值
a[1] = 2; //给数组元素赋值;
3. 默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每元素也被按照实例变量同样的方式被隐式初始化
java">int a2[]= new int[2];// 默认值:0,0
boolean[] b= new boolean[2]; //默认值:false,false
String[] s= new String[2];// 默认值: null, nul!
数组常见操作
数组的遍历
数组元素下标的合法区间:[0,length-1]。我们可以通过下标来遍历数组中的元素,遍历时可以读取元素的值或者修改元素的值。
【例】使用循环初始化和遍历数组
java">public class test03 {public static void main(String[] args) {String[] s = {"北京", "上海", "广州", "深圳"};// 循环for (int i = 0; i < s.length; i++){String name = s[i];System.out.println(name);}System.out.println("---------------------");// 遍历循环for(String i: s) {System.out.println(i);}}
}
数组的拷贝
System.arraycopy (object src, int srcpos, object dest, int destpos, int length)
该方法可以将 src 数组里的元素值赋给 dest 数组的元素,其中 srcpos 指定从 src 数组的第几个元素 开始赋值,length 参数指定将 src 数组的多少个元素赋给 dest 数组的元素。
- src-源数组。
- srcPos-源数组中的起始位置。
- dest-目标数组。
- destPos-日标数据中的起始位置。
- length-要复制的数组元素的数量。
示例
java">public class Test04 {public static void main(String[] args) {Test04 obj = new Test04();obj.copyArr();}// 数组拷贝public void copyArr() {String[] s = {"阿里", "尚学堂", "京东", "搜狐", "网易"};String[] copys = new String[6];System.arraycopy(s, 0, copys, 0, s.length);for (String copy : copys) {System.out.println(copy);}}
}
javautilArrays__170">java.util.Arrays 类
Arrays 类包含了:排序、查找、填充、打印内容等常见的数组操作。
【示例】打印和排序
java">package com.itbaizhan;// 引入Arrays类
import java.util.Arrays;public class Test04 {public static void main(String[] args) {Test04 obj = new Test04();// Arrays.toString 打印obj.usrArraysToString();// 数组排序obj.arraySort();}// 数组打印public void usrArraysToString() {int[] a = { 1,2 };System.out.println(Arrays.toString(a)); // 打印结果:[1, 2]}// 数组排序public void arraySort() {int[] a = {1,2,323,23,543,12,59};System.out.println(Arrays.toString(a)); // 打印结果:[1, 2, 323, 23, 543, 12, 59]Arrays.sort(a);System.out.println(Arrays.toString(a)); // 打印结果:[1, 2, 12, 23, 59, 323, 543]}
}
【】使用 Arrays 类实现二分法查找法
Arrays.binarySearch 是 Java 中用于在 已排序的数组 中快速查找指定元素的方法。它基于 二分查找算法,具有较高的查找效率(时间复杂度为 O(log n))。
public static int binarySearch(int[] a, int key)
- a:要搜索的数组(必须已排序)。
- key:要查找的元素。
- 返回值:
- 如果找到元素,返回其 索引(从 0 开始)
- 如果未找到元素,返回一个 负数,表示元素应该插入的位置(-插入点 - 1)。
java">package com.itbaizhan;// 引入Arrays类
import java.util.Arrays;public class Test04 {public static void main(String[] args) {Test04 obj = new Test04();;// 二分法查找obj.ArraysBinarySearch();}public void ArraysBinarySearch() {int[] a = {1,2,323,23,543,12,59};System.out.println(Arrays.toString(a)); // 打印结果:[1, 2, 323, 23, 543, 12, 59]Arrays.sort(a); // 使用二分法查找,必须先对数组进行排序System.out.println(Arrays.toString(a)); // 打印结果:[1, 2, 12, 23, 59, 323, 543]// 返回排序后新的索引位置,若未找到返回负值System.out.println(Arrays.binarySearch(a, 59)); // 打印结果:4}
}
二分查找的前提是数组必须有序,因此在调用 Arrays.binarySearch() 之前必须先调用 Arrays.sort()。如果数组中存在多个相同的元素,binarySearch 不保证返回哪个元素的索引。如果未找到元素,binarySearch 返回的负值表示该元素在数组中应该插入的位置(从 1 开始计数,取反后减 1)。
【示例】使用 Arrays 类对数组进行填充
Arrays.fill 是 Java 中用于 填充数组 的实用方法。它可以将数组的所有元素(或指定范围内的元素)设置为指定的值。这个方法适用于各种类型的数组,包括基本类型数组和对象数组。
方法签名
Arrays.fill 有多个重载方法,以下是常见的几种:
- 填充整个数组:
public static void fill(int[] a, int val)
- 将数组 a 的所有元素设置为 val。
- 填充指定范围:
public static void fill(int[] a, int fromIndex, int toIndex, int val)
- 将数组 a 中从 fromIndex(包含)到 toIndex(不包含)的元素设置为 val。
java">package com.itbaizhan;// 引入Arrays类
import java.util.Arrays;public class Test04 {public static void main(String[] args) {Test04 obj = new Test04();// 填充obj.arraysFill();}// 使用 Arrays 类对数组进行填充public void arraysFill() {int[] a = {1,2,323,23,543,12,59};System.out.println(Arrays.toString(a)); // 打印结果:[1, 2, 323, 23, 543, 12, 59]Arrays.fill(a, 2, 4, 100); //将2到4的索引的元素替换为100System.out.println(Arrays.toString(a)); // 打印结果: [1, 2, 100, 100, 543, 12, 59]}
}
将数组中指定范围的元素替换为指定值。 Arrays.fill(array, startIndex, endIndex, value)。注意:填充范围是左闭右开区间 [startIndex, endIndex)。
多维数组
多维数组可以看成以数组为元素的数组。可以有二维、三维、甚至更多维数组,但是实际开发中用的非常少。最多到二维数组(学习容器后,我们一般使用容器,二维数组用的都很少)。
- Java中多维数组的声明和初始化应地位到高维的顺序进行
【示例】二维数组的声明
java">package com.itbaizhan;
import java.util.Arrays;// 多维数组的初始化
public class Test06 {public static void main(String[] args) {// Java中多维数组的声明和初始化应地位到高维的顺序进行int[][] a = new int[3][]; // 方式一// int a1[][] = new int[3][]; // 方式二a[0] = new int[2];a[1] = new int[4];a[2] = new int[3];a[0][0] = 100;a[0][1] = 200;System.out.println(Arrays.toString(a[0])); // 打印结果:[100, 200]System.out.println(Arrays.toString(a[1])); // 打印结果:[0, 0, 0, 0]System.out.println(Arrays.toString(a[2])); // 打印结果:[0, 0, 0]int[][] b = {{1, 2, 3},{3,4},{3, 4, 5, 6}};System.out.println(Arrays.toString(b[0])); // 打印结果:[1, 2, 3]System.out.println(Arrays.toString(b[1])); // 打印结果:[3, 4]System.out.println(Arrays.toString(b[2])); // 打印结果:[3, 4, 5, 6]}
}
【示例】二维数组的动态初始化
java">...
public class Test06 {public static void main(String[] args) {...// 二维数组的动态初始化int[][] c = new int[3][];c[0] = new int[]{1, 2, 3};c[1] = new int[]{2, 2};c[2] = new int[]{2, 2, 3, 4};System.out.println(c[2][3]); // 打印结果:4System.out.println(Arrays.toString(a[0])); // 打印结果:[100, 200]System.out.println(Arrays.toString(a[1])); // 打印结果:[0, 0, 0, 0]System.out.println(Arrays.toString(a[2])); // 打印结果:[0, 0, 0]}
}
数组存储表格数据
表格是计算机世界最普遍的模型。使用数组来存储表格数据是非常常见的一种方式。
雇员表
员工编号 | 姓名 | 年龄 | 职位 | 入职日期 |
---|---|---|---|---|
1001 | 高淇 | 18 | 讲师 | 2-14 |
1002 | 高小七 | 19 | 助教 | 10-10 |
1003 | 高小琴 | 20 | 班主任 | 5-5 |
观察表格,发现每一行可以使用一个一维数组存储
Object[] a1 = {1001,“高淇”,18,“讲师”,“2-14”};
Object[] a2 = {1002,“高小七”,19,“助教”,“10-10”};
Object[] a3 = {1003,“高小琴”,20,“班主任”,“5-5”};
注意事项
此处基本数据类型”1001”,本质不是 Object 对象。JAVA 编译器会自动把基本巴类型“自动装箱”成包装类对象。
示例
java">package com.itbaizhan;import java.util.Arrays;public class Test07 {public static void main(String[] args) {Object[] a1 = {1001, "c k k", 18, "讲师", "2-14"};Object[] a2 = {1002, "张小武", 19, "助教", "10-10"};Object[] a3 = {1003, "高小琴", 20, "班主任", "5-5"};Object[][] emps = new Object[3][];emps[0] = a1;emps[1] = a2;emps[2] = a3;/* System.out.println(Arrays.toString(emps[0]));System.out.println(Arrays.toString(emps[1]));System.out.println(Arrays.toString(emps[2])); *//** 打印结果:* [1001, c k k, 18, 讲师, 2-14]* [1002, 张小武, 19, 助教, 10-10]* [1003, 高小琴, 20, 班主任, 5-5]* */for(int i=0;i<emps.length;i++) {for(int j=0;j<emps[i].length;j++) {System.out.print(emps[i][j] + "\t");}System.out.println();}/** 打印结果* 1001 c k k 18 讲师 2-14* 1002 张小武 19 助教 10-10* 1003 高小琴 20 班主任 5-5* */}
}
【示例】使用javabean 和一维数组保存表格信息
雇员表
员工编号 | 姓名 | 年龄 | 职位 | 入职日期 |
---|---|---|---|---|
1001 | 高淇 | 18 | 讲师 | 2-14 |
1002 | 高小七 | 19 | 助教 | 10-10 |
1003 | 高小琴 | 20 | 班主任 | 5-5 |
java">package com.itbaizhan;public class Test08 {public static void main(String[] args) {Emp[] emps = {new Emp(1001, "ckk", 18, "讲师", "2-4"),new Emp(1001, "高大毛", 19, "讲师", "2-4"),new Emp(1001, "ckk", 18, "讲师", "2-4"),new Emp(1001, "ckk", 18, "讲师", "2-4"),};for(Emp e: emps){System.out.println(e);}/** 打印结果:* Emp{id=1001, name='ckk', age=18, job='讲师', hiredate='2-4'}* Emp{id=1001, name='高大毛', age=19, job='讲师', hiredate='2-4'}* Emp{id=1001, name='ckk', age=18, job='讲师', hiredate='2-4'}* Emp{id=1001, name='ckk', age=18, job='讲师', hiredate='2-4'}** */}
}class Emp {private int id;private String name;private int age;private String job;private String hiredate;@Overridepublic String toString() {return "Emp{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", job='" + job + '\'' +", hiredate='" + hiredate + '\'' +'}';}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;}
}
Comparable 接口
Comparable 是 Java 中的一个接口,用于定义对象的自然排序规则。它位于 java.lang 包中,通常用于对对象进行排序(例如在 Collections.sort() 或 Arrays.sort() 中)。
核心方法
Comparable 接口只有一个方法:
java">public interface Comparable<T> {int compareTo(T o);
}
- compareTo(T o):比较当前对象与传入的对象 o,返回一个整数值:
- 负数:当前对象小于传入的对象
- 零:当前对象等于传入的对象
- 正数:当前对象大于传入的对象
多个对象做比较,就要有“比较规则”然后实现排序。
事实上 java 中排序算法的底层也依赖。Comparable 接口。
Comparable 接口中只有一个方法: public int compareTo(Object obj)obj 为要比较的对象
方法中,将当前对象和 obj这个对象进行比较,如果大于返回1,等于返回0,小于返回-1.
【示例】
java">public int compareTo(Object o) {Man2 man = (Man2) o;if (this.age < man.age) {return -1;}if(this.age > man.age) {return 1;}return 0;
}