上节我们讲到了Java中的数组的一维数组,那么这期我将为大家带来Java中的数组的二维数组和对于数组的快速操作
在Java中有包这个概念,每个包中都有许多类,通过使用import来导入Arrays这个方法
借助工具类将参数的数组转化为字符串输出,这样可以更快速的输出
public static int[] func3() {
int[] array1 = {1, 2, 3, 4, 5, 6};
return array1;
}
public static void main(String[] args) {
int[] ret = func3();
//Arrays.toString(ret);用String来接受它的返回值
String s = Arrays.toString(ret);
System.out.println(s);
//Java中提供了java.util.Arrays包,其中包含了一些操作数组的常用方法.
}
public static void main(String[] args) {
int[] ret = new int[]{1, 2, 3, 45, 6};
String str = Arrays.toString(ret);
//这部分要用String接收;
//这是因为本质上是把数组转为字符串从而实现快速输出
//System.out.println(str);
System.out.println(Arrays.toString(ret));
}
public static String myToString(int[] array) {
String s = "[";
for (int i = 0; i < array.length; i++) {
s += array[i];
if (i != array.length - 1) {
s += ",";
}
}
//这部分使用字符串来拼接形成一个数组,但是由于数组的下标小于数组的长度,
//所以当下标不等于长度的数小一个的数的时候,再打逗号,等于时,就不会打了
s += "]";
return s;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] array = new int[n];
for (int i = 0; i < array.length; i++) {
array[i] = sc.nextInt();
}
System.out.println(myToString(array));
}
我们可以使用这个方法来实现对数组的内部数据的一样的数组,那么我们就可以来实现,这个newlength是赋值的长度。 Arrays.copyOf(int[] array,int from Index,int to Index); 这是范围下标引索,基本都是左闭右开
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
int[] copy = Arrays.copyOf(array,array.length);
System.out.println(Arrays.toString(copy));
int[] copy2 = Arrays.copyOf(array,array.length+3);
//此时就相当于扩容了
System.out.println(Arrays.toString(copy2));
int [] copy3 = Arrays.copyOfRange(array,0,3);
//拷贝一定的范围从下标开始,但是一定要记住的是左闭右开,[0,3)
System.out.println(Arrays.toString(copy3));
}
System.arraycopy(原数组,原数组的开始拷贝的位置,目的数组,目的数组开始的位置(下标),拷贝的长度);
public static void main(String[] args) {
//native 本地方法
//本地方法的使用C/C++写的方法,就是快
int[] array = new int[]{1,2,3,4,5};
int[] copy = new int[array.length];
System.arraycopy(array,0,copy,0,array.length);
//System.arraycopy(array,0,copy,0,array.length+2);
//ArrayIndexOutOfBoundsException(就是数组越界了)
System.out.println(Arrays.toString(copy));
}

这个时候就出现了数组的异常,数组访问越界
public static int[] copyOf(int[] array){
int[] copy = new int[array.length];
for (int i = 0; i < array.length; i++) {
copy[i] = array[i];
}
return copy;
}
public static void main8(String[] args) {
int[] array = new int[]{1,2,3,4,5};
System.out.println(Arrays.toString(copyOf(array)));
}int[] 在Java中我们可以在[]中可以写变量,不局限于常量
public static void main(String[] args) {
int[] array = new int[]{1, 2, 3, 4, 5};
int a = 10;
//int[] copy = new int[a];这个部分中的a就是变量
int[] copy = new int[array.length];//同样这部分中也是如此。
for (int i = 0; i < array.length; i++) {
copy[i] = array[i];
}
System.out.println(Arrays.toString(copy));
}
关于拷贝的比较: 上述的拷贝属于深度拷贝 真正的拷贝是把数组的各项的值均复制,但是会创建一个新的空间, 此时的地址也是不同的,但是仅有对象的值是相同的并且对象的位置也是不同的, 拷贝应该是指向的是不同的对象(在堆上),因为它们都是指向不同的对象, 但是在栈上我们可以用发现他们在不同的区域
public static void main(String[] args) {
int[] array =new int[]{1,2,3,4,5};
int[] array1 = array;
System.out.println(Arrays.toString(array1));
} 实际上这种情况不是一种拷贝,因为这种是用array1在Java虚拟机栈上来创建一个变量,同时array在虚拟机栈上也创建了一个变量,首先array指向了它在堆上的对象,然后通过赋值将array的地址传递给array1,这时候就会都指向了同一个对象,所以对谁进行改变都会影响另一个数组的元素的变化
public static int funChx(int[] array,int x) {
for (int i = 0; i < array.length; i++) {
if(array[i]==x){
return i;
}
}
return -1;
}
public static void main3(String[] args) {
int[] array = new int[]{1,2,3,4,5};
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
System.out.println(funChx(array,a));
sc.close();
}
正常的模板:
public static int binarySearch(int[] array,int x){
int left = 0;
int right =array.length;
while(left < right)
{
int mid =(left + right) / 2;
if(x < array[mid]){
right = mid - 1;
}else if(x > array[mid]){
left = mid + 1;
}
else{
return mid;
}
}
return -1;
}
public static void main(String[] args) {
int[] array = new int[]{1,5,4,6,19,3,2,21};
Arrays.sort(array);//与C++中的竞赛中的库函数的sort函数是一样的,如果不写,那么便会从小到大的排序(升序)。
Scanner sc =new Scanner(System.in);
int x = sc.nextInt();
//System.out.println(binarySearch(array,x));
sc.close();
}
适用于竞赛的二分查找,当然这也只是另一种模板,基本表达的意思都差不了太多。
public static int binarySearch2(int[] array,int key) {
int left = 0;
int right = array.length;
while (left + 1 != right) {//判断两者相邻的时候退出循环
int mid = (left + right) / 2;
if (key <= array[mid]) {
right = mid;
} else {
left = mid;
}
}
return right;
} public static void main(String[] args) {
int[] array = new int[]{1,5,4,6,19,3,2,21};
Scanner sc =new Scanner(System.in);
int x = sc.nextInt();
Arrays.sort(array);
System.out.println(Arrays.toString(array));
System.out.println(Arrays.binarySearch(array, x));//用Java中的方法的类来实现二分查找
sc.close();
}
既然能进行二分查找,所以还可以在一定的范围去进行二分查找, binarySearch(int[] arr, int from Index, int to Index, key)
public static void main(String[] args) {
//我们可以在指定的位置去进行二分查找
int[] array = new int[] {24,75,14,32,82789,5700446,34524,6890,5789,24580,2347778,33476678,334342,768876545,8989};
Arrays.sort(array);
System.out.println(Arrays.binarySearch(array,8,14, 5700446));//中间的两个数是范围即是下标
System.out.println(array.length);
System.out.println(Arrays.binarySearch(array,5789));
}
关于sort的讲解,我将会在排序算法中为大家来进行更多排序算法的详细的讲解
数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
public static void main2(String[] args) {
//在Java中我们需要分行去定义,那么就是说{{1,2,3},{4,5,6},{7,8,9}}
//这其中{1,2,3}等都是一行的数字
int[][] array1 = {{1,2,3},{4,5,6},{7,8,9}};//第一种定义
int[][] array2 = new int[][]{{1,2,3},{4,5,6},{7,8,9}};//这个时候我们不在[][]不能写
int[][] array3 = new int[2][3];//这个时候不能定义{}(大括号),这个时候全是默认的0;
//array[行的坐标][列的坐标]
//遍历数组
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(array1[i][j] + " ");
}
System.out.println();
}
}
二维数组是一种特殊的一维数组,这一点在Java中体现得淋漓尽致;在Java中的二维数组,会有i行j列,那么每行获得的地址是不同的,假设有2行3列的二维数组,那么我们就会发现两行的元素所存的地址是不同的。 array1 = {{1,2,3},{4,5,6}};第1行,地址位0x123,那么通过虚拟机栈指向堆中的对象{1,2,3},第2行也是如此,它的地址为0x1423,那么通过虚拟机栈指向堆中的对象{4,5,6}, 所以我们发现了在二维数组中有两个地址,那就表明了我们可以理解为一个特殊的一维数组。

上述每个行的首元素其实是储存的是地址,所以我们也可以把它当作两个一维数组来进行理解
public static void main(String[] args) {
int[][] array1 = {{1,2,3},{4,5,6}};
System.out.println(array1[0]);
System.out.println(array1[1]);
System.out.println("================");
System.out.println(Arrays.toString(array1[0]));
System.out.println(Arrays.toString(array1[1]));
System.out.println("================");
System.out.println(array1[0].length);//一行元素的长度
System.out.println(array1[1].length);//一行元素的长度
//所以我们可以理解为是两个一维数组array[0],array[1]
System.out.println("================");
System.out.println(array1.length);//这个表示有多少行
} 
public static void main(String[] args) {
int[][] array1 = {{1,2,3},{4,5,6}};
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
System.out.print(array1[i][j] + " ");
}
System.out.println();
}
//利用将其转化为字符串来进行打印
String ret = Arrays.deepToString(array1);
//我们需要进行深度打印,在tostring前面加上了deep即可
System.out.println(ret);
} 
二维数组在Java中我们可以去不用定义列,所以我们可以省略列的定义,其实我们可以对行元素去进行一维数组的定义
public static void main(String[] args){
int[][] array = new int[2][];
//二维数组在Java中我们可以去不用定义列,所以我们可以省略列的定义
//其实我们可以对行元素去进行一维数组的定义
array[0] = new int[]{1,2,3};
array[1] = new int[]{4,5,6,7,8,9};
//上述这个操作,可指定某一行元素是为不规则的,但是我们不用去定义列
System.out.println(Arrays.deepToString(array));
}
public static void main(String[] args) {
int[][] array = new int[2][];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
上述我们出现空指针的错误 NullPointerException;因为我们知道了在二维数组中的行的定义是存储地址,通过地址指向在行中定义的列的元素,没有定义列,所以在行的定义它就会存不到地址 初始化没有赋值,那么它就会出现了这种情况。
好了,今天的分享就到这里了,如果有哪些不足,欢迎大家在评论区指出!下期我将为大家带来关于Java中的类与对象的知识点讲解。