Java 数组
什么是数组?
Java 数组是存放在连续内存空间
上的,存储同类型数据
的,且数组本身长度固定
的容器。
数组的定义格式
// 第一种定义格式:数据类型[] 数组名
int[] arr;
double[] arr;
char[] arr;
// 第二种定义格式:数据类型 数组名[]
int arr[];
double arr[];
char arr[];
数组的动态初始化
数组动态初始化是指只给定数组的长度,而由系统给出默认的初始值。
格式:数据类型[] 数组名 = new 数据类型[数组长度];
public class Test {
public static void main(String[] args) {
int[] iArray = new int[5];
System.out.println(iArray); // [I@4554617c
byte[] bArray = new byte[5]; // [B@74a14482
System.out.println(bArray);
}
}
[I@4554617c
打印说明:
@
:分隔符。[
:当前的空间是一个数组类型。I
:当前数组容器中所存储的数据类型。4554617c
:十六进制内存地址。
数组索引
每一个存储到数组的元素,都会自动拥有一个编号,从 0 开始。
这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
访问数组元素格式:数组名[索引];
public class Test {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr); // 数组的内存地址 [I@4554617c
// 数组名[索引]:访问数组容器中的空间位置
System.out.println(arr[0]); // 0 系统自动分配的默认初始化值
System.out.println(arr[1]); // 0
System.out.println(arr[2]); // 0
System.out.println("--------------");
// 给指定索引位的元素赋值:数组名[索引] = 值
arr[0] = 11;
arr[1] = 22;
arr[2] = 33;
System.out.println(arr[0]); // 11
System.out.println(arr[1]); // 22
System.out.println(arr[2]); // 33
}
}
数组的内存分配
内存是计算机中的重要原件,是临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,且运行完毕后会清空内存。
Java 虚拟机要运行程序,必须要对内存进行空间的分配和管理。
Java 中的内存分配:
一个数组的内存分配:
两个数组的内存分配:
多个数组指向相同的内存:
数组的静态初始化
数组的静态初始化是指在创建数组时,就直接将元素确定。
// 完整版格式
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, ...};
// 简化版格式
数据类型[] 数组名 = {元素1, 元素2, ...};
示例:
public static void main(String[] args) {
// 数据类型[] 数组名 = new 数据类型[]{数据1, 数据2, 数据3...};
int[] arr = new int[]{11, 22, 33};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
// 数据类型[] 数组名 = {数据1, 数据2, 数据3...};
int[] arr2 = {44, 55, 66};
System.out.println(arr2);
System.out.println(arr2[0]);
System.out.println(arr2[1]);
System.out.println(arr2[2]);
}
数组的遍历
数组遍历,就是将数组中的每个元素分别获取出来。遍历也是数组操作中的基石。
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
// for 循环实现数组遍历
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
}
}
示例:获取数组中的最大值
public class Test {
public static void main(String[] args) {
int[] arr = {11, 4, 65, 34, 76, 23};
// 初始化最大值为首位元素
int maxValue = arr[0];
// 从索引[1]开始的元素依次与当前最大值比较
for(int i=1; i<arr.length; i++){
// 若当前元素值比最大值大,则将其赋值给最大值
if(arr[i] > maxValue){
maxValue = arr[i];
}
}
// 打印最终结果
System.out.println(maxValue);
}
}
示例:数组元素求和
键盘录入 5 个整数,存储到数组中,并对数组求和。
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 初始化长度为 5 的数组
int[] arr = new int[5];
// 初始化结果
int sumResult = 0;
Scanner sc = new Scanner(System.in);
for(int i=0; i<5; i++){
System.out.println("请输入需要存储的第"+(i+1)+"个整数:");
arr[i] = sc.nextInt();
sumResult += arr[i];
}
// 打印最终结果
System.out.println(sumResult);
}
}
示例:数组的元素索引位查找
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 初始化长度为 5 的数组
int[] arr = {12, 43, 55, 77, 34, 54, 23, 52, 76};
// 初始化索引,若元素不存在则返回索引值为-1
int index = -1;
Scanner sc = new Scanner(System.in);
System.out.println("请输入需要查找的元素:");
int targetValue = sc.nextInt();
for(int i=0; i<arr.length; i++){
if(arr[i]==targetValue){
System.out.println("索引值为:"+i);
break;
}
}
}
}
示例:已知一个数组 arr = {19, 28, 37, 46, 50}; 用程序实现把数组中的元素值交换,交换后的数组 arr = {50, 46, 37, 28, 19},并在控制台输出交换后的数组元素。
public class Test {
public static void main(String[] args) {
int[] arr = {19, 28, 37, 46, 50};
int start = 0;
int end = arr.length - 1;
while(start < end){ // for(; start<end; start++)
int tmp = arr[start];
arr[start] = arr[end];
arr[end] = tmp;
start++;
end--;
}
// 打印最终结果
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]+" "); // 50 46 37 28 19
}
}
}
二维数组
二维数组也是一种容器,不同于一维数组,该容器存储的元素是一维数组。
动态初始化
格式:数据类型[][] 变量名 = new 数据类型[m][n];
- m 表示这个二维数组,可以存放多少个一维数组。
- n 表示每一个一维数组,可以存放多少个元素。
// 示例
int[][] arr = new int[3][3];
静态初始化
完整格式:数据类型[][] 变量名 = new 数据类型[][]{{元素1, 元素2, ...}, {元素1, 元素2, ...}, ...};
简化格式:数据类型[][] 变量名 = {{元素1, 元素2, ...}, {元素1, 元素2, ...}, ...};
示例:
public class Test {
public static void main(String[] args) {
int[][] arr = {{11, 22, 33}, {44, 55, 66}};
System.out.println(arr[0][2]);
int[] arr1 = {11, 22, 33};
int[] arr2 = {44, 55, 66};
int[][] array = {arr1, arr2};
System.out.println(array[0][2]);
}
}
示例:二维数组遍历
public class Test {
public static void main(String[] args) {
int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for(int i=0; i<arr.length; i++){
for(int j=0; j<arr[0].length; j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
内存空间
示例:int[][] rating = new int[3][4];
这个二维数组在内存空间可不是一个 3*4 的连续地址空间,而是由四条连续的地址空间组成的:
Arrays(数组工具类)
Arrays 的常用方法:
-
二分查找(数组需要有序)
- public static int binarySearch(int[], int args)
- public static int binarySearch(double[], double args)
-
数组排序
- public static void sort(int[])
- public static void sort(char[])
-
数组的字符串形式
- public static String toString(int[])
-
复制数组
- public static T[] copyOf(T[] original, int newLength)
- original:源数组
- newLength:新数组的长度
- public static T[] copyOf(T[] original, int newLength)
-
复制数组的一部分
- public static T[] copyOfRange(T[] original, fromIndex, toIndex)
- original:源数组
- fromIndex:开始截取的索引位
- toIndex:结束截取的索引位(不包含)
- public static T[] copyOfRange(T[] original, fromIndex, toIndex)
-
比较两个数组的元素值(包括元素顺序)是否完全一致
- public static boolean equals(T[], T[])
-
将数组转成集合(集合转数组:list.toArray())
- public static List<T> List asList(T[])
-
将数组转成流
public static Stream Arrays.stream()
示例:
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
// public static String toString(int[] a):返回指定数组的内容的字符串表示形式
int [] arr1 = {3, 2, 4, 6, 7};
System.out.println(Arrays.toString(arr1)); // 字符串:[3, 2, 4, 6, 7]
// public static void sort(int[] a):按照数字顺序排列指定的数组
int [] arr2 = {3, 2, 4, 6, 7};
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2)); // 字符串:[2, 3, 4, 6, 7]
// public static int binarySearch(int[] a, int key):利用二分查找返回指定元素的索引
// 1. 数组必须有序
// 2. 如果要查找的元素存在,那么返回的是这个元素实际的索引
// 3. 如果要查找的元素不存在,那么返回的是 (-插入点-1)
// 插入点:如果这个元素在数组中,他应该在哪个索引上
int [] arr3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int index = Arrays.binarySearch(arr3, 0);
System.out.println(index); // -1
// public static List<T> List asList(T[]):数组转集合
// 方式一
List<String> list = Arrays.asList("a", "b", "c");
System.out.println(list); // ["a", "b", "c"]
// 方式二
int[] a1 = new int[]{1, 2, 3};
Integer[] a2 = new Integer[]{1, 2, 3};
String[] s1 = new String[]{"1", "2", "3"};
System.out.println(Arrays.asList(a1)); // [[I@3af49f1c] ,存储的是int[]这个数组对象
System.out.println(Arrays.asList(a2)); // [1, 2, 3] ,存储的是每个数组的元素
System.out.println(Arrays.asList(s1)); // [1, 2, 3] ,存储的是每个数组的元素
// Arrays.asList(T[]).stream()
// 求数组总和
int [] arr4 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int total = Arrays.stream(arr4).sum();
// 数组遍历
Arrays.asList(a1).stream().forEach(x -> System.out.println(x.getClass().getName())); // [I
Arrays.asList(a2).stream().forEach(x -> System.out.println(x.getClass().getName())); // java.lang.Integer
Arrays.asList(s1).stream().forEach(x -> System.out.println(x.getClass().getName())); // java.lang.String
}
}