数组的定义
在Java中,数组是用来存储一组相同数据类型的数据结构,它属于引用数据类型。
数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问它们。数组的四个基本特点:
-
长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
-
其元素的类型必须是相同类型,不允许出现混合类型。
-
数组类型可以是任何数据类型,包括基本类型和引用类型。
-
数组变量属于引用类型,数组也是对象。
定义数组语法:
-
数据类型[] 数组名 = new 数据类型[数组长度];
-
数据类型 数组名[] = new 数据类型[数组长度];获得数组的长度使用数组的属性length。我们通过数组的变量名(数组的整地址),通过数组的变量名加上数组的下标或者索引可以对数组的每一个值进行操作。
数组元素分配的初始值
数组元素类型 | 默认初始值 |
---|---|
byte、short、int、long | 0 |
float、double | 0.0 |
char | ‘\u0000’ |
boolean | false |
引用数据类型 | null |
数组元素的表示与赋值
由于定义数组时内存分配的是连续的空间,所以数组元素在数组里顺序排列编号。
该编号即元素下标。首元素编号为0,因此数组的下标依次是0、1、2、3、···
访问数组中的元素可以通过下标:数组名[下标值]
scores[0]=65;//表示scores数组中的第一个元素赋值为65
数组的初始化
定义数组并初始化:数组的长度由value的数量来决定。
数据类型[] 数组名 = {值1, 值2,……}
数据类型[] 数组变量名 = new 数据类型[]{值1,值2,值3,……}
//定义数组并初始化数组
//创建一个长度为4的整型数组
int scores[] = {75,58,78,96};
int score[] = new int[]{75,58,78,96};
数组问题
1、索引越界
class Demo{
public static void main(String[] args){
//定义了一个不定长度的int类型的数组
int[] array = {12,4,5,24,78,94};
//获得数组的长度
System.out.println("数组的长度:"+array.length);
System.out.println("打印指定数组的值:"+array[6]);
}
}
此时数组长度为6,下标最大为5,而打印了数组下标为6的值,没有这个值。
2、空指针异常
public static void main(String[] args) {
int[] arr = {1,3,5};
System.out.println(arr[0]);//1
//null只能赋值给引用变量,null覆盖掉了原有的地址值
//一旦覆盖掉地址值,就无法通过arr找到这个数组
//数组都找不到了,无法访问里面的元素
arr = null;
System.out.println(arr[0]);//空指针异常
//java.lang.NullPointerException
}
数组在内存中的划分
内存区分配:
栈内存:容量小,速度快,数据的生命周期短,先进后出,保存局部变量(函数里面的变量,语句块中的变量)。
堆内存:容量大,速度慢,保存引用数据类型的数据。
方法区:保存所有对象的共享数据。
栈中存储堆中数组的首地址
引用类型数组初始化
数组的常用操作
1、遍历
即把整个数组每个数都访问一遍。
for循环
int[] array = {12,4,5,24,78,94};
for (int i=0;i<array.length;i++) {
System.out.println(array[i]);
}
增强for:jdk1.5之后提供了增强for循环语句,用来实现对数组或集合中元素的访问。
语法:for(元素类型 变量名:要循环的数组或集合名){···}
第一个元素类型是数组或集合中元素的类型,变量名在循环时用来保存每个元素的值,冒号后面是要循环的数组或集合名称。
int[] array = {12,4,5,24,78,94};
for (int i:array) {
System.out.println(i);
}
2、求极值
public static void main(String[] args) {
//求12,4,5,24,78,94中的最大值和最小值
int[] array = {12,4,5,24,78,94};
int max = array[0];//存储最大值
int min = array[0];//存储最小值
//判断最值
for (int i=0;i<array.length;i++) {
//最大
if (array[i]>max){
max = array[i];
}
//最小
if (array[i]<min) {
min = array[i];
}
}
System.out.println("最大值:"+max);
System.out.println("最小值:"+min);
}
3、排序
冒泡排序(Bubble sort):相邻的两个数逐个的做比较,如果前一个数比后一个数小那么就交换过来,当第一轮比较完毕后最小的值一定产生在末尾。
public static void main(String[] args) {
int[] array = {23, 25, 12, 7, 51};
int temp;//使用temp交换两个数的位置
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
//增强for遍历数组
for (int i : array) {
System.out.println(i);
}
//结果为:7 12 23 25 51
}
选择排序:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
public static void main(String[] args) {
/* 数组:{23,25,12,7,51}
23,25,12,7,51
假设min=23,用min与25,12,7,51比较,最后min=7
7,23,25,12,51
7,12,23,25,51
7,12,23,25,51
7,12,23,25,51
7,12,23,25,51
第一次:arr[0]分别与arr[1-4]比较,比较4次
第二次:arr[1]分别与arr[2-4]比较,比较3次
第三次:arr[2]分别与arr[3-4]比较,比较2次
第四次:arr[3]与arr[4]比较,比较1次
*/
int[] array = {23, 25, 12, 7, 51};
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] > array[j]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
//增强for遍历数组
for (int i : array) {
System.out.println(i);
}
//7 12 23 25 51
}
倒置
获得数组中间的索引length/2
。获得中间索引前的索引的对称端的索引length -1 – i
public static void main(String[] args) {
int[] array = {11,2,3,4,5,66,55};
for (int i = 0; i < array.length / 2; i++) {
int temp = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temp;
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
4、添加
//String[] str = {"aaa","bbb","ccc",null}
//String[] str = {"aaa","bbb","ccc","ddd"}
public static void main(String[] args) {
int index = -1;
String[] str = {"aaa","bbb","ccc",null};
for (int i = 0; i < str.length; i++) {
if (str[i]==null){
index = i;
break;
}
}
if (index!=-1){//数组中存在元素为null
str[index] = "ddd";
for (int i = 0;i<str.length;i++){
System.out.println(str[i]);
}
}else {
System.out.println("数组已满");
}
}
5、修改
//String[] str = {"aaa","bbb","ccc","eee"}
//String[] str = {"aaa","bbb","ccc","ddd"}
public static void main(String[] args) {
int index = -1;
String[] str = {"aaa","bbb","ccc","eee"};
for (int i = 0; i < str.length; i++) {
if (str[i].equals("eee")){//比较值是否相等
index = i;
break;
}
}
if (index!=-1){
str[index] = "ddd";
for (int i = 0;i<str.length;i++){
System.out.println(str[i]);
}
}else {
System.out.println("不存在eee");
}
}
6、删除
思路:找到删除的位置,删除后把后面的数据依次前移将最后一位设置为null。
//String[] str = {"aaa","zzz","bbb","ccc"}
//String[] str = {"aaa","bbb","ccc",null}
public static void main(String[] args) {
int index = -1;
String[] str = {"aaa","zzz","bbb","ccc"};
for (int i = 0; i < str.length; i++) {
if (str[i].equals("zzz")){//比较值是否相等
index = i;
break;
}
}
if (index!=-1){
for (int i = index;i<str.length-1;i++){
str[i] = str[i+1];
}
str[str.length-1] = null;
}else {
System.out.println("没有找到要删除的元素zzz");
}
for (int j = 0; j <str.length ; j++) {
System.out.println(str[j]);
}
}
二维数组
定义:Java中定义和操作多维数组的语法和一维数组类似。在实际应用中,三维及以上的数组很少使用,主要使用二维数组。
//数据类型[][] 数组名;
//数据类型 数组名[][];
int[][] num; //定义二维数组
num = new int[3][4]; //分配内存空间
//或者 int[][] num = new int[3][4];
存储方式:
二维数组实际上是一个一维数组,它的每个元素又是一个一维数组。
初始化:
//定义二维数组并初始化
//方法一
int[][] scores = new int[][]{{90,78,54},{45,86},{96}};
//方法二
int[][] score = {{90,78,54},{45,86},{96}};
遍历:
int[][] scores = {{90,78,54},{45,86},{96}};
for (int i = 0; i <scores.length ; i++) {
for (int j = 0; j <scores[i].length ; j++) {
System.out.println(scores[i][j]);
}
}
//90 78 54 45 86 96
Arrays类
Arrays类及常用方法
JDK中提供了一个专门用于操作数组的工具类,即Arrays类,位于java.util包中。该类提供了一系列的方法来操作数组,用户直接调用这些方法即可。
返回类型 | 方法 | 说明 |
---|---|---|
boolean | equals(array1,array2) | 比较两个数组是否相等 |
void | sort(array) | 对数组元素升序排序 |
String | toString(array) | 将数组转化为一个字符串 |
void | fill(array,val) | 将数组元素都赋值为val |
与array数据类型一致 | copyOf(array,length) | 将数组复制成一个长度为length的新数组 |
int | binarySearch(array,val) | 查询元素值val在数组中的下标 |
使用Arrays类操作数组
equals():当两个数组长度相等,对应位置的元素也一一相等时,返回true,否则返回false。
import java.util.Arrays;
//使用Arrays中的方法时要导入java.util中的Arrays类
public class demo{
public static void main(String[] args) {
int[] arr1 = {10,20,30};
int[] arr2 = {10,20,30};
int[] arr3 = {10,20};
System.out.println(Arrays.equals(arr1,arr2));//true
System.out.println(Arrays.equals(arr1,arr3));//false
}
}
sort():对数组元素升序排序,即从小到大。
import java.util.Arrays;
public class demo{
public static void main(String[] args) {
int[] arr = {15,20,4,9,3};
Arrays.sort(arr);
for (int i:arr) {
System.out.println(i);//3 4 9 15 20
}
}
}
toString():按顺序把多个数组连在一起,多个数组元素之间用英文逗号和空格隔开。
import java.util.Arrays;
public class demo{
public static void main(String[] args) {
int[] arr = {15,20,4,9,3};
String s = Arrays.toString(arr);
System.out.println(s);//[15, 20, 4, 9, 3]
}
}
fill(arr,n):使用n填充数组arr中的每一个元素。
import java.util.Arrays;
public class demo{
public static void main(String[] args) {
int[] arr = {15,20,4,9,3};
Arrays.fill(arr,1);
String s = Arrays.toString(arr);
System.out.println(s);//[1, 1, 1, 1, 1]
}
}
copyOf():复制一个新数组。
import java.util.Arrays;
public class demo{
public static void main(String[] args) {
int[] arr = {15,20,4,9,3};
//将arr复制成长度为3的新数组arrnew1
int[] arrnew1 = Arrays.copyOf(arr,3);
System.out.println(Arrays.toString(arrnew1));//[15, 20, 4]
//将arr复制成长度为4的新数组arrnew2
int[] arrnew2 = Arrays.copyOf(arr,4);
System.out.println(Arrays.toString(arrnew2));//[15, 20, 4, 9]
//将arr复制成长度为5的新数组arrnew3
int[] arrnew3 = Arrays.copyOf(arr,5);
System.out.println(Arrays.toString(arrnew3));//[15, 20, 4, 9, 3]
}
}
binarySearch():查询元素在数组中的下标。
调用该方法时要求数组中的元素已经升序排列,这样才能得到正确的结果。
import java.util.Arrays;
public class demo {
public static void main(String[] args) {
int[] arr = {15,20,4,9,3};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));//[3, 4, 9, 15, 20]
int index = Arrays.binarySearch(arr,3);
System.out.println(index);//0
}
}
Comparable接口
想对某个类的对象之间做比较,就需要实现Comparable接口。接口中只有一个方法compareTo(),这个方法定义了对象之间的比较规则。依据这个”比较规则“,我们就能对所有对象实现排序。
事实上,Java中排序算法的底层也依赖Comparable接口。Comparable接口中只有一个方法:
public int compareTo(Object obj),obj为要比较的对象。
方法中,将当前对象和obj这个对象进行比较,如果大于返回1,等于返回0,小于返回-1。compareTo方法的代码也比较固定,案例如下:
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Man[] man = {
new Man("aa",15),
new Man("bb",10),
new Man("cc",20)
};
Arrays.sort(man);
System.out.println(Arrays.toString(man));
//[Man{name='bb', age=10}, Man{name='aa', age=15}, Man{name='cc', age=20}]
}
}
class Man implements Comparable {
String name;
int age;
public Man(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object o) {
Man man = (Man) o;
if (this.age < man.age ) {
return -1;
}
if (this.age > man.age ) {
return 1;
}
return 0;
}
@Override
public String toString() {
return "Man{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
评论区