Java数组的定义与使用
1.数组的基本概念
1.1 数组的定义
数组可以是相同类型的元素的一个集合。在内存中是一段连续的空间。
1.2 数组的创建以及初始化
数组的和初始化有以下两种方式:
int[] arr2=new int[]{1,2,3,4,5,6}; //这种是静态初始化
int[] arr3=new int[10]; //这种是动态初始化(也就是只在内存中开辟了一块内存空间)
这个new暂时看成一个语法,它的作用是创建一个对象。
动态初始化::在创建数组时,直接指定数组中元素的个数
静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定
注意事项:
- 静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
- 静态初始化时, {}中数据类型必须与[]前数据类型一致。
- 静态初始化可以简写,省去后面的new T[]。
// 注意:虽然省去了new T[], 但是编译器编译代码时还是会还原
int[] array1 = {0,1,2,3,4,5,6,7,8,9};
double[] array2 = {1.0, 2.0, 3.0, 4.0, 5.0};
String[] array3 = {“hell”, “Java”, “!!!”};- 静态和动态初始化也可以分为两步,但是省略格式不可以(也就是不能够把new int 给省略了)。
int[] array1;
array1 = new int[10];
int[] array2;
array2 = new int[]{10, 20, 30};
// 注意省略格式不可以拆分, 否则编译失败
// int[] array3;
// array3 = {1, 2, 3}
1.3 比较java数组与C语言数组
首先在创建上:
C语言版本是:int a[10]={0};
java的版本是:int[] a = {0};
二者“[]”的位置不同;
其次在默认初始化上:
C语言若是没有初始化,则数组里面的内容是“随机值”
java语言若是没有初始化,则数组里面的内容是“0”(这一点也体现了java相对于其他编程语言的安全性)
类型 | 默认值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0 |
float | 0.0f |
double | 0.0 |
char | /u0000 |
boolean | false |
引用类型 | null |
1.4 遍历数组
方法一(这个与C语言是一样的):
for (int i = 0; i < n; i++) {
}
方法二:(这个是新知识)
增强for循环:for each循环
int[] arr={1,2,3,4,5,3,32,3};
for(int x:arr)
{
System.out.println(x);
}
//运行结果:
1
2
3
4
5
3
32
3
Process finished with exit code 0
1.5 求数组的长度
java中求长度的方法:数组名.length
这个也是与C语言不一样的地方,在C语言中我们使用 “sizeof()”
但是在java中我们直接 “arr.length” 就可以求出arr数组的长度
2.数组的类型与使用
2.1 数组的类型
数组是引用类型。
在java里面一共有两种类型的数据:
基本数据类型:该变量空间中直接存放的是其所对应的值
引用数据类型:其空间中存储的是对象所在空间的地址(这个就类似于C语言的指针)
2.2 理解数组名
数组名就是一个地址,并且两个数组名之间可以画等号,意义是赋值地址
见下面代码分析:
int[] arr1 = {1,2,3,4,5};
int[] arr2 = {100,200,300};
arr1 = arr2;
System.out.println(arr[1]);
//输出的结果是:
100
这又是一个与C语言不同的点,C语言的数组名是万万不可直接相等的,但是java却可以
2.3 数组的使用
2.3.1 保存数据
public static void main(String[] args) {
int[] array = {1, 2, 3};
for(int i = 0; i < array.length; ++i){
System.out.println(array[i] + " ");
}
}
在这段代码中,“+” 的作用是用来连接字符串。在循环中,每次打印都会将数组中的元素和一个空格连接起来,然后输出到控制台。这样可以使得每个数组元素都以空格分隔开来,并逐行打印出来。
2.3.2 作为函数的参数(也就类似于传递指针变量)
类似于C语言的指针
public static void main(String[] args) {
int[] arr = {1, 2, 3};
func(arr);
System.out.println("arr[0] = " + arr[0]);
}
//方法
public static void func(int[] a) {
a[0] = 10;
System.out.println("a[0] = " + a[0]);
}
// 执行结果
a[0] = 10
arr[0] = 10
发现在func方法内部修改数组的内容, 方法外部的数组内容也发生改变.
因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的。
2.3.3 作为函数的返回值
返回的同样是一个地址,只要注意返回的数组类型与main里面赋值的数组类型一致就可以了
也就是说不能 返回值是int[],但是在main里面却是char[] = fun()(fun的返回值就是int[],类型不一致)
2.4 操作数组的常用的方法
首先需要包含java.util.Arrays
2.4.1 数组转字符串
函数是:Arrays.toString();
代码示例:
import java.util.Arrays
int[] arr = {1,2,3,4,5,6};
String newArr = Arrays.toString(arr);
System.out.println(newArr);
// 执行结果
[1, 2, 3, 4, 5, 6] //(中括号和逗号都是有的)
2.4.2 数组拷贝
2.4.2.1 Arrays.copy0f()
这个方法有两个参数,第一个参数是拷贝目标的地址,第二个参数是创建数组的长度
代码举例:
int[] arr={1,2,3,4,5};
int[] arr2=Arrays.copyOf(arr,arr.length);
System.out.println(Arrays.toString(arr2));
// 结果是
[1, 2, 3, 4, 5, 0]
如果我们所创建的数组,也就是Arrays.copy0f()方法的第二个参数如果大于拷贝空间的长度,由于java函数的安全性,并不会越界访问,而是会给多余的部分初始化为0;
2.4.2.2 Arrays.copyOfRange()
这个方法有三个参数,功能是实现从制定位置的拷贝
Arrays.copyOfRange(source, from, to);
代码举例:
int[] arr={1,2,3,4,5};
int[] arr2=Arrays.copyOfRange(arr,2,4);
System.out.println(Arrays.toString(arr2));
// 运行结果是:
[3, 4]
这里明明是从2到4为什么只打印了两个数呢?
因为在java中一般区间都是左闭右开也就是说是**[2 , 4)**
2.4.3 数组排序(升序排序)
这个排序其实与冒泡排序类似,总之在java里面提供了一个方法,能够用来对数组进行排序:
Arrays.sort()
直接上代码:
int[] arr={2,6,3,1,9,4};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//结果
[1, 2, 3, 4, 6, 9]
3.在数组中查找指定的元素
3.1 顺序查找
顺序查找也就是遍历数组进行查找
见代码:
public static void main(String[] args) {
int[] arr = {1,2,3,10,5,6};
System.out.println(find(arr, 10));
}
// 写成了一个方法,不写也可以
public static int find(int[] arr, int data) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == data) {
return i;// 返回的是下标
}
}
return -1; // 表示没有找到
}
// 执行结果
3
3.2二分查找
前提条件:只是和**有序数组**(升序或降序)
思路是:
以升序数组为例, 二分查找的思路是先取中间位置的元素, 然后使用待查找元素与数组中间元素进行比较:
- 如果相等,即找到了返回该元素在数组中的下标
- 如果小于,以类似方式到数组左半侧查找
- 如果大于,以类似方式到数组右半侧查找
代码举例:
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
System.out.println(binarySearch(arr, 6));
}
// 同样是封装成了一个方法
public static int binarySearch(int[] arr, int toFind) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (toFind < arr[mid]) {
// 去左侧区间找
right = mid - 1;
} else if (toFind > arr[mid]) {
// 去右侧区间找
left = mid + 1;
} else {
// 相等, 说明找到了
return mid;
}
}
// 循环结束, 说明没找到
return -1;
}
// 执行结果
5
4.二维数组
在这里希望大家可以回忆一下二维数组的本质,也就是特殊的一维数组,在使用上java中的二维数组与C语言中的二维数组是一样的,并没有什么区别,唯一不同的可能就是在初始化的省略上有一点小区别
在C语言中我们都知道,二维数组可以省略“行”,但是不能省略“列”。
但是在java里面却是可以省略“列”,但是不能省略“行”。
基本语法:数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
代码示例:
int[][] arr = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
for (int row = 0; row < arr.length; row++) {
for (int col = 0; col < arr[row].length; col++) {
System.out.printf("%d\t", arr[row][col]);
}
System.out.println("");
}
// 执行结果
1 2 3 4
5 6 7 8
9 10 11 12
5.总结
以上就是java中的数组,总的来说还是有许多地方与C语言不一样的,比如说初始化的方式,中括号的位置,以及处理数组的“函数”还有二位数组的省略区别,并且java中的数组与C语言中的指针类似,是可以直接赋值的!