数组定义
数组是相同类型数据的有序集合。
相当于装东西的容器。
数组描述的是相同类型的若干个数据,按照一定的先后次序排序组合而成。其中,每一个数据称作为一个元素,每个元素可通过索引(下标)来访问。
创建数组语法
- 数据类型 [] 数组名称 = new 数据类型[长度]
int []arr=new int[5];
arr[0]=1;
arr[1]=2;
arr[2]=3;
arr[3]=4;
arr[4]=5;
- 数据类型 [] 数组名称 = new 数据类型 [] {元素,元素,元素}
int arr[]=new int []{1,2,3,4,5};
- 数据类型 数组名称 [] = {};
int arr []={1,2,3,4,5};
数组的声明
- 声明一个数组的时候并代表着数组真正被创建
- 构造一个数组,必须指定其长度
- 声明数组的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才会分配内存空间,此时才与长度有关
- 数组名称和[ ]交换顺序是可以的
数组的基本特点
- 数组长度是确定的。一旦数组被创建,其大小就不可以再改变
- 数组的元素必须是相同类型的,不允许出现混合类型。元素的类型可以是任意Java支持的类型(基本类型 + 引用类型)
- 数组的元素在堆内存中被分配空间,并且是连续分配的
- 使用new关键字对数组进行内存的分配。每个元素都会被JVM赋予其默认值。
默认规则:
整数: 0
浮点数: 0.0
字符: \u0000
布尔: false
引用类型: null - 数组的元素都是有序号的,序号从0开始,0序的。称作数组的下标、索引
栈用于存放数组,堆用于存放数组元素
数组的优缺点
优点:
- 可保存若干个数据
- 随机访问的效率高。根据下标访问元素效率高(元素连续分配空间)
缺点:
- 数组的元素的类型必须一致
- 连续分配空间在堆中,如果数组的元素很多,对内存的要求更加的严格
- 删除元素、插入元素效率比较低,需要移动大量的元素
- 数组定长,不能自动扩容
- 数组没有封装,数组对象只提供了一个数组长度的属性,但是没有提供方法用来操作元素
数组常见问题
数组越界:ArrayIndexOutOfBoundsException
int [] arr = new int [3];
System.out.println(arr[3]);
空指针异常: NullPointerException
arr=null;
System.out.println(arr[0]);
数组的遍历
For循环:
public class Test{
public static void main(String[] args){
int [] arr = new int[4];
// 初始化数组元素
for(int i=0;i<arr.length;i++){
arr[i]=2*i+1;
}
//读取元素的值
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
For-each循环
public class Test{
public static void main(String[] args){
String [] str = {"a","bb","ccc","dddd"};
for(String s : str){
System.out.println(s);
}
}
}
二维数组
二维数组初始化
- 静态初始化
数据类型 [ ][ ] 数组名称 = {{元素1,元素2,…},{元素1,元素2,…},…};
eg: int [ ][ ] arr={{10,11,12},{20,21,22},{30,31,32,};
静态初始化可用于不规则二维数组的初始化
public static void main(String[]args){
int [][] arr=new int[][]{{1,2,3,4},{5,6},{7,8,9}};
//输出行数
System.out.println(arr.length);
//输出列数
System.out.println(arr[0].length);
}
- 动态初始化
数据类型 数组名 [ ][ ] = new 数据类型[m][n]
数据类型 [ ][ ] 数组名 = new 数据类型[m][n]
数据类型 [ ] 数组名 [ ] = new 数据类型[m][n]
eg: int [ ][ ] arr=new int [5][3]; 也可以理解为“5行3列”
二维数组的遍历
public class Test {
public static void main(String[] args) {
int [][] arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
System.out.println("遍历二维数组:");
// 外层for循环 遍历行
for (int i = 0; i < arr.length; i++) {
// 内层for循环 遍历列
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
运行结果:
Arrays工具类
JDK 提供了一个工具类专门用来操作数组的工具类,即 Arrays。
Arrays工具类只有静态方法。
常用方法:
- toString() 将数组转化为字符串
- sort() 将数组升序排列,是一个改进的快速排序,比起传统的冒泡,选择排序速度更快
- binarySearch() 二分法查找数组,返回值为int型
- asList() 将数组转化成固定大小的集合
- equals 比较两数组是否相等
- contains 检查数组是否包含某个值
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int [] arr = new int []{9,8,7,1,2,3,6,5,4};
int [] arr1 = new int []{1,2,3,4,5,6,7,8,9};
//sort() 将数组升序排列,是一个改进的快速排序,比起传统的冒泡,选择排序速度更快
Arrays.sort(arr);
// toString() 将数组转化为字符串,有多个重载方法,可以支持boolean、float、int、long、short对象数组。
// 若直接打印arr,则显示该对象的Hash值
System.out.println(Arrays.toString(arr));
System.out.println(arr);
System.out.println();
// arr已经使用过sort()方法,因此arr已从小到大排序好
// == 比较
System.out.println("arr==arr1: "+(arr==arr1));
// equals 比较
System.out.println("Arrays.equals(arr,arr1): "+Arrays.equals(arr,arr1));
System.out.println();
// 检查数组是否包含某个值
String [] arr2 = new String[]{"a","b","c","d"};
boolean bool = Arrays.asList(arr2).contains("a");
boolean bool2 = Arrays.asList(arr2).contains("e");
System.out.println(Arrays.toString(arr2));
System.out.println("arr中是否包含a:"+bool);
System.out.println("arr中是否包含e:"+bool2);
System.out.println();
// binarySearch(Object[] a, Object key) 二分法查找元素
System.out.println("元素3在arr数组中的索引是:"+Arrays.binarySearch(arr,3)); //输出元素3所在的索引:2
}
}
运行结果如下