作者简介:爱塔居的博客_CSDN博客-领域博主
专栏:Java学习
作者简介:大三学生,希望跟大家一起进步!
文章简介:关于Java数组的定义与使用。
目录
数组是用来存储一组相同数据类型的数据的,可以看成是相同类型元素的一个集合。数组在内存中是一段连续的空间,且每个空间都有自己的编号。
T[]数组名=new T[N]
T:表示数组中存放元素的类型
T[]:表示数组的类型
N:表示数组的长度
int [] array1 = new int [ 10 ]; // 创建一个可以容纳 10 个 int 类型元素的数组double [] array2 = new double [ 5 ]; // 创建一个可以容纳 5 个 double 类型元素的数组String [] array3 = new double [ 3 ]; // 创建一个可以容纳 3 个字符串元素的数组
数组的初始化主要分为动态初始化以及静态初始化
1.动态初始化:在创建数组时,直接指定数组中元素的个数
2.静态初始化:在创建数组时不直接指定数组元素个数,而是直接将具体的数据包内容进行指定
- public class Test2 {
- public static void main(String[] args) {
- int[] array1={1,2,4};//第一种:动态初始化
- int[] array2=new int[]{1,2,3};//第二种 静态初始化
- int[] array3=new int[3];//第三种
- }
- }
相比于第一种,第二种和第三种定义数组的语句中出现了new。在Java中的数组其实就是一个对象。所以我们会说:Java当中,一切皆对象。一般通过new关键字来实例化对象,在这里就是创建一个数组。如果在第一种或者第二种的中括号中加数字是会报错的,无论填的多少。
【注意事项】
1.金泰初始化,虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
2.静态初始化时,{}中数据类型必须与[]前数据类型一致。
3.静态初始化,第一种和第二种结果没有区别,第一种就是省去了new T[]。虽然省去了new T[],但是编译器在编译代码时还是会还原的。
4.数组虽然可以按照C语言个数创建:int arr[]={1,2,3},但是很不推荐@
5.静态和动态初始化也可以分成两步:
int[] array1;
array1=new int[10];
int[] array2;
array2=new int[]{10,20,30};
🎈🎈注意:如果省略new T[]的语句,必须一行写完,不能分步。
6.如果没有对数组进行初始化,数组中元素有其默认值。如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值。
类型 | 默认值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0 |
float | 0.0f |
double | 0.0 |
char | /u0000 |
boolean | false |
如果数组中存储元素类型为引用类型,默认值为null。
🎉🎉数组在内存中是一段连续的空间,空间的编号都是从0开始的,依次递增,该编号称为数组的下标,也可以说是数组的索引。数组可以通过下标访问其任意位置的元素。
【注意】
1.数组是一段连续的内存空间,因此支持随机访问,即通过下标快速访问数组中任意位置的元素
2.下标从0开始,介于【0,N)之间,N为元素个数,不能越界,
- public class Test2 {
- public static void main(String[] args) {
- int[] array = {1, 2, 3};
- System.out.println(array[3]);//error
- }
- }
报错:
所谓“遍历”是指将数组中的所有元素都访问一遍,访问是指对数组在的元素进行某种操作,比如打印。
int [] array = new int []{ 10 , 20 , 30 , 40 , 50 };System . out . println ( array [ 0 ]);System . out . println ( array [ 1 ]);
- import java.util.Arrays;
- public class Test2 {
- public static void main(String[] args) {
- int[] array=new int[]{1,2,3,4,5,6};
- //1
- for (int i = 0;i < array.length;i++){
- System.out.println(array[i]);
- }
- //2 for-each遍历数组
- for (int x:array){
- System.out.println(x);
- }
- //3
- String ret=Arrays.toString(array);
- System.out.println(ret);
- }
- }
内存是一段连续的存储空间,主要用来存储程序运行时数据的。如果对内存中存储的数据不加区分的随意存储,那对内存管理起来将会非常麻烦。
🍊🍊 JVM对所使用的内存按照功能的不同进行了划分:
3.2 基本数据类型遍历与引用类型变量的区别
基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的时其所对应的值,其中byte、short、int、long、float、double、char、boolean都是基本数据类型。
引用数据类型创建的变量,一般称为对象的引用,并不直接存储对象,可以简单理解为存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以操作对象。
🍉🍉这边我们直接放代码:
- import java.util.Arrays;
- public class Test2 {
- public static void main(String[] args) {
- int[] array1= {1,2,3,4};
- array1[0]=99;
- int[] array2=array1;
- array2[0]=100;
- System.out.println(Arrays.toString(array1));
- System.out.println(Arrays.toString(array2));
- }
- }
这个输出结果应该是什么呢?
我们可以浅浅地画一张图(并不规范就是帮助理解用):
像是一台空调,有两个遥控器,无论是哪一个调低温度,空调的度数都会变低。
🥝🥝那我们再看下面的代码:
- import java.util.Arrays;
- public class Test2 {
- public static void main(String[] args) {
- int[] array1={1,2,3,4};
- int[] array2={11,22,33,44};
- array1=array2;
- array1[0]=1888;
- System.out.println(Arrays.toString(array1));
- System.out.println(Arrays.toString(array2));
- }
- }
这个程序的输出结果又会是如何呢?
此时没有人引用{1,2,3,4}这个对象了,它就会被系统回收。
🍇🍇
总结:通过其中任何一个引用修改对象的值,另一个引用去访问的时候,也是被改变的。
null在Java中表示“空引用”,也就是一个不指向对象的引用,表示一个无效的内存位置。因此不能堆这个内存进行任何读写操作,一旦尝试读写,就会抛出NullPointerException(空指针异常)。
不是说Java没有指针吗?怎么会有空指针?这跟老婆饼里没有老婆是一个说法。
注意:Java中并没有约定null和0号地址的内存有任何关联。
- public class Test2 {
- public static void main(String[] args) {
- int[] array=null;
- System.out.println(array);
- }
- }
描述:int[] array=null,意味着array这个引用不指向任何对象。
输出结果如下👇
我们再看看下面的代码:
- public class Test2 {
- public static void main(String[] args) {
- int[] array=null;
- System.out.println(array[0]);
- }
- }
既然array不指向任何对象,array[0]的结果又会是怎么样的呢?
空指针异常也称为NPE,会伴随我们的Java生涯。
不过我们可以根据编译器给的提示行号去查找原因。
🍈(1)我们看一下这个代码,想思考一下输出结果应该是什么?
- import java.util.Arrays;
- public class Test2 {
- public static void main(String[] args) {
- int[] array1={1,2,3,4};
- func1(array1);
- System.out.println(Arrays.toString(array1));
- }
- public static void func1(int[] array){
- array=new int[]{15,16,17};
- }
- }
输出结果:[1,2,3,4]
只是改变了形参的指向,并没有改变实参的指向。
(2)
- import java.util.Arrays;
- public class Test2 {
- public static void main(String[] args) {
- int[] array1={1,2,3,4};
- fun2(array1);
- System.out.println(Arrays.toString(array1));
- }
- public static void fun2(int[] array){
- array[0]=99;
- }
- }
输出结果:[99, 2, 3, 4]
总结:当数组作为参数进行传递的时候,其实还是按值传递的,不过传递的值是一个地址。
1.形参修改指向,只会影响形参的指向
2.形参修改指向对象的值,这才会影响到实参
🧀1.
- import java.util.Arrays;
- public class Test2 {
- public static void main(String[] args) {
- int[] array=new int[]{1,2,3,4};
- int[] array1=Arrays.copyOf(array,array.length);
- System.out.println(Arrays.toString(array1));
- }
- }
这边引入了一个新东西:Arrays.copyOf(原始数组,新的长度)进行拷贝数组。
2.
- import java.util.Arrays;
- public class Test2 {
- public static void main(String[] args) {
- int[] array=new int[]{1,2,3,4};
- int[] ret=new int[array.length];
- System.arraycopy(array,0,ret,0,Math.min(array.length,ret.length));
- System.out.println(Arrays.toString(ret));
- }
- }
这是本地方法,特点是底层是由C/C++代码实现的。
public stative native void arraycopy(Object src,int srcPos,Object dest,int desPos,intnlength);
其中:
sec:从哪里拷贝
srcPos:从拷贝数组的哪个位置开始拷贝
dest:拷贝到哪里
destPos:从拷贝数组的拷贝到哪个位置
length 就是拷贝多长
//创建数组[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] int[] array=new int[10]; Arrays.fill(array,-1); System.out.println(Arrays.toString(array));
以及sort(),toString(),copyOf(),equal()需要了解一下下用法。