Java SE 2 --- 数组

求数组长度:
数组名+.length

1. 数组的三种定义

1. int [] array1 = {1, 2, 3};//直接赋值,静态初始化
2. int[] array2 = new int[]{1, 2, 3, 4};//

没有本质区别,只有写法上的区别
还有一种定义方式:

3. int[] array3 = new int[10]; 
//动态初始化
//只分配内存,没有赋值,只有默认值0

静态和动态初始化也可以分为两步,但是省略格式不可以

int[] arrary1;
arrary1 = new int[10];
int[] arrary2;
arrary2 = new int[10, 20, 30];
省略格式不可以拆分

为什么省略格式不可以拆分:
因为像数组,结构体这种聚合类型,整体初始化的机会只有一次,
如果数组中存储元素类型为引用类型,默认值为null

2. 数组的三种遍历方式

数组的遍历有三种方式:

  1. 使用for循环,类似于c语言遍历
  2. 使用for each (增强for循环):
public class Test {
    public static void main(String[] args){
        int[] arrary1 = {1, 2, 3};
        for (int x:arrary1) {
            System.out.print(x + " ");
        }
    }
}

区别是第二种方法无法得到数组下标,无法对指定元素进行修改
3. java中有一个"工具", 可以专门用来操作数组,这个工具叫做Arrays

import java.util.Arrays;

public class Test {
    public static void main(String[] args){
        int[] arrary1 = {1, 2, 3};
//        for (int x:arrary1) {
//            System.out.print(x + " ");
//        }
        String ret = Arrays.toString(arrary1);
        //吧数组转变成字符串,然后输出
        System.out.println(ret);
    }
}

在这里插入图片描述

3. 引用类型

众所周知,数组是一种引用数据类型,什么是引用呢?

3.1初始JVM的内存分布

众所周知,内存是一块连续的空间
在这里插入图片描述1. 虚拟机栈:,与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表,操作数栈,动态链接,返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息.比如:局部变量.当运行结束后,栈帧就销毁了,即栈帧中保存的数据也被销毁了
2. 本地方法栈:底层是c或者c++代码,与虚拟机栈作用相似,只不过保存的内容是Native方法的局部变量,在有些版本的JVM实现中(例如HotSpot),本地方法栈和虚拟机栈是一起的
3. :Jvm管理的最大内存区域,使用new创建的对象都是在堆上保存,堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁
4. 程序计数器:只是一个很小的空间,保存下一条执行的指令的地址
5. 方法区:用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.方法编译出的字节码就是保存在这个区域
这里主要关心堆和虚拟机栈
在这里插入图片描述由此引出引用
array其实就是一个引用变量,array这个引用,存放一个地址,指向一个对象,当引用的是局部变量时,就存放在虚拟机栈区
**注意:**引用变量是一个局部变量,存储在栈区,也就是array存放在栈区,但是数组是一个对象,存放在堆区,当局部变量所在的函数程序执行完,局部变量被回收后,所引用的对象也就随之被回收
对象的被回收是因为没人再引用他

3.2 再谈引用

import java.util.Arrays;
public class Test {
    public static void main(String[] args){
        int[ ] array = {1, 2, 3};
        System.out.println(Arrays.toString(array));
        int[] array1 = array;
        array1[1] = 99;
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(array1));
    }
}

看运行结果:
在这里插入图片描述2.
在这里插入图片描述由以上可得出:

一个引用不能同时指向多个对象
一个对象可以被多个引用所指向

当一个数组不知该初始化为何值时,可以写成:

  1. int[] array = null; 这句代码代表这个引用不指向任何的对象
    当以后引用不知该指向哪个对象,就可以指向null
    但是当引用不指向任何对象时,就不能对该引用做任何的操作,否则会报错说空指针异常
  2. 当写成int[] array = 0;时会报错,因为0属于基本数据类型,而array属于引用数据类型

null的作用类似于c语言中的NULL(空指针),都是表示一个无效的内存位置,因此不能对这个内存进行任何的读写操作,一旦尝试读写,就会报错空指针异常
在c语言中NULL表示0号地址,0号地址收到保护,不能进行任何的访问,但是java中的null与0号地址没有任何关联

4. 数组的应用场景

4.1 作为函数的参数

函数传参数组类型为引用数据类型
看下面两个方法

public static void array1(int[] array){
        array = new int[10];
    }
public static void array2(int[] array){
        array[1] = 99;
    }

依次调用,输出array数组中的值:
1.

import java.util.Arrays;
public class Test {
    public static void array1(int[] array){
        array = new int[10];
    }
    public static void array2(int[] array){
        array[1] = 99;
    }
    public static void main(String[] args){
        int[] array = {1, 2, 3};
        array1(array);
        //array2(array);
        System.out.println(Arrays.toString(array));
    }
}

运行结果为:
在这里插入图片描述2.

public class Test {
    public static void array1(int[] array){
        array = new int[10];
    }
    public static void array2(int[] array){
        array[1] = 99;
    }
    public static void main(String[] args){
        int[] array = {1, 2, 3};
        array1(array);
        array2(array);
        System.out.println(Arrays.toString(array));
    }
}

在这里插入图片描述出现这两种运行结果的原因是:
所谓的"引用"本质上只是存了一个地址,第一个方法中是改变了该方法中引用所指向的对象(形参自己的指向),而第二个方法是改变了所指向的对象的内容

4.2 数组作为返回值

c语言中不支持直接返回一个数组,但java可以,看代码:

public static int[] array3(){
        int[] array = {1, 2, 3};
        return array;
    }
    public static void main(String[] args) {
        int[] array = array3();
        System.out.println(Arrays.toString(array));
    }

在这里插入图片描述

5. 数组习题

5.1 Array.toString()方法的实现:

public class Test {
    //toString方法的实现
    public static String my_ToString(int[] array){
        if (array == null)
            return "null";
        String ret = "[";
        for (int i = 0; i < array.length; i++){
            ret +=array[i];
            if (i != (array.length - 1)){
                ret += ",";
            }
        }
        ret += "]";
        return ret;
    }
    public static void main(String[] args){
        int[] array = {1,2,3};
        String ret = my_ToString(array);
        System.out.println(ret);
    }
}

5.2 Arrays.copyOf()的实现

注意:数组当中存储的是基本数据类型时,不论怎么拷贝都不会出现问题,但如果存储引用型,拷贝时需要考虑深浅拷贝的问题,关于深浅拷贝在后续接口的文章中进行阐述

5.2.1 拷贝的4种方式
public static void main(String[] args){
        int[] array = {1, 3, 4, 5};
        int[] array1 = array;
    }

没有产生新的空间,不算拷贝

import java.util.Arrays;

public class Test {
    //toString方法的实现
    public static String my_ToString(int[] array){
        if (array == null)
            return "null";
        String ret = "[";
        for (int i = 0; i < array.length; i++){
            ret +=array[i];
            if (i != (array.length - 1)){
                ret += ",";
            }
        }
        ret += "]";
        return ret;
    }
    public static void main1(String[] args){
        int[] array = {1,2,3};
        String ret = my_ToString(array);
        System.out.println(ret);
    }
    //数组拷贝的实现
    public static void main(String[] args){
        int[] array = {1, 3, 4, 5};
        //数组拷贝的实现1
        int[] array1 = new int[array.length];
        for (int i = 0; i < array.length; i++){
            array1[i] = array[i];
        }
        //数组拷贝的实现2
        int[] array2 = Arrays.copyOf(array1, array1.length);
        //数组拷贝的实现3
        int[] array3 = new int[array.length];
        System.arraycopy(array, 0, array3, 0, array.length);
         //数组的拷贝实现4
        int[] array5 = array.clone();
        //打印拷贝的数组
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(array1));
        System.out.println(Arrays.toString(array2));
        System.out.println(Arrays.toString(array3));
        System.out.println(Arrays.toString(array5));
    }
}

在这里插入图片描述这里一共有五个参数,按顺序分别是要拷贝的数组,拷贝的初始位置,要拷贝到的目标数组,拷贝到目标数组的起始位置,拷贝的长度,此拷贝方法支持局部拷贝.

5.5.2 Arrays.copyOfRange()

相比于上面介绍道德copyOf,这里新增的参数可以设置拷贝的范围

int[] array4 = Arrays.copyOfRange(array, 0, 3);

这里的参数0和3代表的是array数组的下标,注意此处是左闭右开的,意思就是下标为3的那个元素不会被拷贝,如果想要拷贝array的所有元素,那么最后一个参数的值为array的长度+1

5.3 看方法源码:ctrl + b 或者 ctrl + 鼠标左键

5.4 看方法索引:alt + 7 或者 Strutture

在这里插入图片描述

5.5 native 修饰的方法

native修饰的方法底层是由C/C++代码写的
在这里插入图片描述在这里插入图片描述要想看到native修饰的方法具体的实现代码,需要看JVM的源码
如果将JVM看成是一个软件,那么这个软件是由C/C++代码实现的

5.6 将数组升序排列

Arrays.sort(array);

5.7 二分查找的实现

5.7.1 my_BinarySearch
import java.util.Arrays;
import java.util.Scanner;

public  class Test {
    //数组的二分查找
    public static int BinarySearch(int[] array, int a){
        int left = 0;
        int right = array.length - 1;
        while (left <= right){
            int mid = (left + right) >>> 1;
            if (array[mid] < a){
                left = mid + 1;
            }else if (array[mid] > a){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
    public static void main(String[] args){
        int[] array = {23, 41, 13, 67, 97, 35, 68, 78};
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));
        Scanner scan = new Scanner(System.in);
        int a = scan.nextInt();
        System.out.println(BinarySearch(array, a));
    }
}
5.7.2 Arrays.binarysearch
Arrays.binarySearch(array, 41);

5.8 数组逆序

public static void back(int[] array){
        int left = 0;
        int right = array.length - 1;
        while(left < right){
            int num = array[left];
            array[left] = array[right];
            array[right] = num;
            right--;
            left++;
        }
    }
    public static void main(String[] args){
        int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        back(array);
        System.out.println(Arrays.toString(array));
    }

5.9 判断两数组是否相等

Arrays.equals(array, array1);
public static void main(String[] args){
        int[] array = {1, 2, 3, 4, 5, 6, 7};
        int[] array1 = {1, 2, 3, 4, 5, 6, 7};
        int[] array2 = {1, 2, 3, 4, 5, 6, 9};
        boolean a = Arrays.equals(array, array1);
        boolean b = Arrays.equals(array1, array2);
        System.out.println(a);
        System.out.println(b);
    }

5.10 数组赋同一值

5.10.1 数组所有元素赋同一值
Arrays.fills(array, -1);

5.10.2 数组部分元素赋同一值

Arrays.fill(array, 2, 5, -1)//左闭右开

6. 二维数组

6.1 二维数组的三种定义方式

1. int[][] = new int[2][3];
2. int[][] = new int[][]{{1, 2, 3}, {4, 5, 6}};
3. int[][] = {{1, 2, 3}, {4, 5, 6}};

6.2 二维数组的三种打印方式

1. 使用双重for循环
	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();
	}
2. Arrays.deeptoString(array)
3. 双重增强for循环
 for(int[] arr : array){
 	for(int i : arr){
 		System.out.print(i + " ");
 	}
 		System.out.println();
 }

6.3 不规则二维数组

c语言中二维数组定义时不能省列,java中二维数组不能省行,可以省列,省列时可用于定义不规则数组

int[][]array = new int[3][];
        array[0] = new int[]{1, 2, 3};
        array[1] = new int[]{4, 5, 6, 7};
        array[2] = new int[]{8, 9, 10, 11};

7. 题外知识 — Java中断言的使用

此部分内容转载,参考大佬博客

https://wenku.baidu.com/view/b36bf9f483eb6294dd88d0d233d4b14e85243ef0.html
主要内容:本文详细介绍了一种QRBiLSTM(分位数回归双向长短期记忆网络)的时间序列区间预测方法。首先介绍了项目背景以及模型的优势,比如能够有效利用双向的信息,并对未来的趋势上限和下限做出估计。接着从数据生成出发讲述了具体的代码操作过程:数据预处理,搭建模型,进行训练,并最终可视化预测结果与计算分位数回归的边界线。提供的示例代码可以完全运行并且包含了数据生成环节,便于新手快速上手,深入学习。此外还指出了模型未来发展的方向,例如加入额外的输入特性和改善超参数配置等途径提高模型的表现。文中强调了时间序列的标准化和平稳检验,在样本划分阶段需要按时间序列顺序进行划分,并在训练阶段采取合适的手段预防过度拟合发生。 适合人群:对于希望学习和应用双向长短时记忆网络解决时序数据预测的初学者和具有一定基础的研究人员。尤其适用于有金融数据分析需求、需要做多一步或多步预测任务的从业者。 使用场景及目标:应用于金融市场波动预报、天气状况变化预测或是物流管理等多个领域内的决策支持。主要目的在于不仅能够提供精确的数值预计还能描绘出相应的区间概率图以增强结论置信程度。 补充说明:本教程通过一个由正弦信号加白噪构造而成的简单实例来指导大家理解和执行QRBiLSTM流程的所有关键步骤,这既方便于初学者跟踪学习,又有利于专业人士作为现有系统的补充参考工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

With Order @!147

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值