JavaSE(数组)

1. 数组

数组创建及初始化

总结:
三种写法包括了动态初始化和静态初始化,其中省略格式不能再省略(拆分);没有初始化时(默认值为基类类型对应的默认值)其中引用类型的默认值为null

三种写法
1. 动态初始化:在创建数组时,直接指定数组中元素的个数
   int[] array = new int[10];
2. 静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容
   进行指定。静态初始化时, {}中数据类型必须与[]前数据类型一致。
   double[] array2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};
3.静态初始化可以简写,省去后面的new T[]
  String[] array3 = {"hell", "Java", "!!!"};

静态和动态初始化也可以分为两步,但是省略格式不可以
int[] array1;
array1 = new int[10];
int[] array2;
array2 = new int[]{10, 20, 30};

注意省略格式不可以拆分, 否则编译失败
int[] array3;
array3 = {1, 2, 3};

数组遍历

在数组中可以通过 数组对象.length 来获取数组的长度

1.for循环方式
int[]array = new int[]{10, 20, 30, 40, 50};
	for(int i = 0; i < array.length; i++){
		System.out.println(array[i]);
	}
2.使用 for-each 遍历数组
int[] array = {1, 2, 3};
	for (int x : array) {//这里的x可以只是个标识,和下面对应即可
		System.out.println(x);
	}
作用:for-each 是 for 循环的另外一种使用方式. 
能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错
3.借助Java的操作数组的工具类 Arrays 
import java.util.Arrays;//工具类 Arrays 
public class UseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,3,2,5,4};
        Array.sort(array);//工具类 Arrays 排序
        String str = Arrays.toString(array);
        // 创建一个字符串变量来接收它的返回值
        System.out.println(str);
        // 因为 Arrays.toString 是有返回值(必须有),所以可以直接输出
         System.out.println(Arrays.toString(array));
    }
}

数组空间(重点)

局部变量在栈上,new的对象在堆上
**引用很像指针,最大的区别就是不能对 引用 解引用,可以对指针解引用,**因为在Java没有传址的概念的,其他功能类似,但时两个东西,不是同一个东西,不能混淆在一起。

有个问题就诞生了,指针有空指针,那引用有空引用(引用里面存的地址是空的)吗?
答案是有的,只不过跟C语言不同,C是大写NULL,Java是小写null
但是请注意,举这个例子只是为了让你理解引用是一个什么东西,顺便区别两者。
C的东西只是辅助你理解Java,尽量学Java的时候,抛开C,两者(引用和指针)有很多不同地方。

在这里插入图片描述

public class UseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        int[] array1 = null;
        //当一个引用被赋予null,就代表这该引用不指向任何对象
        // 既然该引用不指向任何对象,那么我这样写代码会怎么样?
        System.out.println(array1.length);//error
        // 求一个空引用所指向的对象的长度,但是空引用不会指向任何一个对象的
        System.out.println(array1[0]);
        // 这个写法毫无疑问也是错的,没对象,你怎么访问对象里的东西?
    
    }
}

数组作为参数(重点)

案例一:
import java.util.Arrays;
public class UseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        func1(array);
        System.out.println(Arrays.toString(array));//1,2,3,4,5

    }
    public static void func1(int[] array){
        array = new int[]{11,2,13,4,51};
    }

}

案例二:
import java.util.Arrays;
public class UseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        func2(array);
        System.out.println(Arrays.toString(array));//99,2,3,4,5
    }
    public static void func2(int[] array){
        array[0] = 99;
    }
}

解析:案例一的结果还是array原来的值,并没有发生改变;fun1()只是创建了一个新的空间,也没有返回值。只是将array的实参地址重新赋值(地址0x99—>0x66)
案例二的结果发生了改变,借助array存储的地址,访问并修改了成员变量(array[0])
总结:通过其中任何一个引用修改这个对象的值,另一个引用去访问的时候,也是被改变的。

在这里插入图片描述
还有一个问题值得讨论:一个引用 是否 能同时 指向 多个对象?
答案是不能, 一个引用只能指向一个对象(一个引用只能保存一个对象的地址)

   public static void main(String[] args) {
       int[] array1 = new int[]{1,2,3,4,5};
       array1 = new int[10];
       array1 = new int[2];
       array1 = new int[4];
   }
   此时的array1,存储的地址,已经被改变(array是一个局部变量,意味着存的值是可以被改变的),
   现在存的是 new int[4] 的这个对象的地址, 而不是说,存几个对象的地址。

数组作为方法的返回值

(代码示例: 写一个方法, 将数组中的每个元素都 * 2)
先写没有返回值的

import java.util.Arrays;

public class UseOfArrays {
    public static void main(String[] args) {
        int[] array={1,2,3,4,5};
        func(array);
        System.out.println(Arrays.toString(array));
    }
    public static void func(int[] array){
        for (int i = 0; i < array.length; i++) {
            array[i]=2*array[i];
        }
    }
}

在这里插入图片描述
写有返回值的

不破坏原有数组:另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比较高效.有的人可能会说,方法调用完的时候,不是会销毁栈上的空间,我们这样将地址带回来,不会存在一些问题吗?请注意 new 的对象,都是存在堆上的,而不是栈上。这里的返回的是将堆上对象的地址(注意返回类型int[]),而不是局部变量ret,所以不会出现问题。

import java.util.Arrays;

public class TheDefinitionAndUseOfArrays {
    public static void main(String[] args) {
        int[] array={1,2,3,4,5};
         int[] ret = func(array);//建立数组类型(对象)变量来接收
        System.out.println(Arrays.toString(ret));
        System.out.println(Arrays.toString(array));
    }
    public static int[] func(int[] array){//新建对象(数组)
         int[] ret = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            ret[i]=2*array[i];
        }
        return ret;//这里返回是 新建对象(数组),在堆上的地址
    }
}

在这里插入图片描述

深拷贝和浅拷贝

有面试官问你某个程序实现了某种拷贝?
回答:想怎么拷贝?拷贝值就是深拷贝;拷贝地址就是浅拷贝。

在这里插入图片描述
在这里插入图片描述

数组拷贝

方法1 循环拷贝
方法2: 利用Java提供的函数: Arrays.copyOf()
方法3:Arrays.copyOfRange()左闭右开区间
方法4: System.arraycopy(array,0,array2,0,array.length)
方法5:克隆:数组名.clone();

方法1 循环拷贝
import java.util.Arrays;

public class UseOfArrays {
    public static void main(String[] args) {
        int[] array={1,2,3,4,5};
        int[] array2 = copyshuzu(array);// 是方法中 引用ret存储值的一份拷贝,能够访问 ret 指向的堆上的对象
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(array2));
    }
    public static int[] copyshuzu(int[] array){
        int[] ret = new int[array.length];//创一个相同类型,元素个数相同的 数组变量array2来接收 array 的元素
        for (int i = 0; i < array.length; i++) {
            ret[i] = array[i];//通过 对应的下标进行复制拷贝
        }
        return  ret;// 将对象的地址转过去
    }
}

方法2: 利用Java提供的函数: Arrays.copyOf()
import java.util.Arrays;

public class UseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        int[] array2 = Arrays.copyOf(array,array.length);
        System.out.println(Arrays.toString(array2));//
        // 既然能规定 拷贝数量,我输入拷贝数量超过,源数组array的元素个数呢?
        int[] array3 = Arrays.copyOf(array,array.length*2);
        System.out.println(Arrays.toString(array3));
    }
     //但是注意一点,本质是copy明白嘛? 这扩容出来的数组,跟元素组,不是同一个数组
     //如果我们想"扩容",输入的倍数必须整数,因为它的长度类型规定为整形
}
方法3:Arrays.copyOfRange()左闭右开区间
import java.util.Arrays;

public class UseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        int[] ret = Arrays.copyOfRange(array,0,4);
        System.out.println(Arrays.toString(ret));//1,2,3,4
    }
}
方法4:对法二的改进
import java.util.Arrays;

public class TheDefinitionAndUseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        int[] array2 = new int[array.length];
        System.arraycopy(array,0,array2,0,array.length);
        // 跟用for循环进行拷贝时一个道理,根据对应的下标进行赋值拷贝
        System.out.println(Arrays.toString(array2));
    }
}
方法5:克隆
import java.util.Arrays;

public class UseOfArrays {
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        int[] array2 = array.clone();// 类似 副本: 可以理解为是一份资料的备份
        System.out.println(Arrays.toString(array2));
    }
}

2.二维数组

创建

  1. 数据类型[][] 数组名 = { 初始化数据 }
  2. 数据类型[][] 数组名 = new 数据类型[][]{ 初始化数据 }
  3. 数据类型[][] 数组名 = new 数据类型[行][列数]
public class TheDefinitionAndUseOfArrays {
    public static void main(String[] args) {
        // 创建一个 2行3列的二维数组
        int[][] array = {{1,2,3},{4,5,6}};
        int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
        int[][] array3 = new int[2][3];
    }
}

遍历

方法1: array[下标].length,就能得到相对应的一维数组(对象)的元素个数(长度)。

在这里插入图片描述

public class UseOfArrays {
    public static void main(String[] args) {
        int[][] array = {{1,2,3},{4,5,6}};
        print(array);
        // 这里我们在用实例证明一下
        // array.length 是否能的得到 行数 2
        System.out.println(array.length);
        // array[下标].length 是否能得到 列数3
        System.out.println(array[0].length);
        System.out.println(array[1].length);
    }
    public static void print(int[][] array){
        // 按照我们以前对C的理解,二维数组的存储模式应该为
        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(数组名)

import java.util.Arrays;

public class TheDefinitionAndUseOfArrays {
    public static void main(String[] args) {
        int[][] array = {{1,2,3},{4,5,6}};
        System.out.println(Arrays.deepToString(array));
    }
}

特别的二维数组

int[][] array = {{1,2},{1,2,3}};

在这里插入图片描述

意义在于我们可以改,去赋予这种二维数组,我们将其称为 不规则的二维数组
在C语言中,二维数组,是不能省略列的,行可以省略
而Java与之相反,行不能省略,列可以
int[][] array = new int[2][];
array[0]=new int[3];// 意味着第一个数组长度为3
array[1]=new int[2];// 意味着第二个数组长度为2

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值