Java 一维数组概述 一维数组扩容和拷贝

鳄鱼君

发表文章数:643

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Java » Java 一维数组概述 一维数组扩容和拷贝

Java语言中的数组是一种引用数据类型,不属于基本数据类,数据的父类是Object。数组实际上是一个容器,可以同时容纳多个元素(数组是一个数据的集合),数组当中可以存储基本数据类的数据,也可以存储引用数据类的数据。因为数组是引用数据类型,所以数组是存储在堆内存中的

  1. 数组当中如果存储的是“java对象”的话,实际上存储的是对象的“引用(内存地址)”
  2. 数组一旦创建,在java中规定,长度不可变
  3. 数组的分类:一维数组、二维数组、三维数组、多维数组
  4. 所有的数组对象都有length属性,用来获取数组中元素的个数
  5. java中的数组要求数组中元素的类型唯一,例如int类型数组只能存储int类型
  6. 数组在内存方面存储的时候,数组中的元素内存地址是连续的
  7. 数组中每一个元素都有下标,小标从0开始,最后一个元素的下标是length-1

一维数组优点

查询/检索某个下标上的元素时效率较高,因为每一个元素的内存地址在空间上存储是连续的,每一个元素类型相同,所以占用的空间大小一样,知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以,通过一个数学表达式就可以计算出某个下标上元素的内存地址,直接通过内存地址定位元素,所以数组的检索效率最高

一维数组缺点

由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增删元素涉及到后面元素统一向前或向后位移操作,但是数组中最后一个元素的增删没有影响。数组不能存储大数据量,因为在内存空间上,找不到一块特别大的连续的内存空间

声明/定义一个一维数组

int[] array1;
double[] array2;
boolean[] array3;
String[] array4;
Object[] array5;

初始化一维数组:

// 静态初始化
int[] array1 = {100, 200, 300, 400};

// 动态初始化
int[] array1 = new int[5]; // 5表示数组内元素的个数,每个元素默认值0
String array2 = new String[5]; // 数组内元素个数为5,每个元素默认值null

静态初始化一个int类型的数组:

public class ArrayTest {
    public static void main(String[] args) {
        // 声明一个int类型数组,静态初始化
        int[] array1 = {100, 200, 300, 4000};
        // 数组中每一个元素都有下标,所有的数组都有length属性
        System.out.println(array1.length);
        System.out.println("第一个元素" + array1[0]);
        System.out.println("最后一个元素" + array1[array1.length - 1]);

        // 修改
        array1[0] = 110;
        array1[array1.length - 1] = 0;
        System.out.println("第一个元素" + array1[0]);
        System.out.println("最后一个元素" + array1[array1.length - 1]);

    }
}

数组的遍历:

public class ArrayTest {
    public static void main(String[] args) {
        // 声明一个int类型数组,静态初始化
        int[] array1 = {100, 200, 300, 4000};
        for (int i = 0;i < array1.length;i++){
            System.out.println("第" + i + "个元素是" + array1[i]);
        }
        // 超过数组下标取值会报错
        // java.lang.ArrayIndexOutOfBoundsException
        // System.out.println(array1[5]);
    }
}

动态数组初始化:

public class ArrayTest {
    public static void main(String[] args) {
        // 声明一个int类型数组,动态初始化
        // 创建长度为5的int数组,数组中,每个元素默认值0
        int[] array1 = new int[5];
        for (int i = 0; i < array1.length; i++){
            System.out.println(array1[i]);
        }
    }
}

当创建数组的时候,确定数组中存储哪些具体的元素时,采用静态初始化方式;当创建数组的时候,不确定数组中存储哪些数据,可以采用动态初始化的方式,预先分配内存空间

方法的参数是数组

public class ArrayTest {
    public static void main(String[] args) {
        // 调用方法的时候传一个数组
        int[] array1 = {100, 2000, 400, 5000};
        printArray(array1);
    }
    public static void printArray(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
}
public class ArrayTest {
    public static void main(String[] args) {
        // 调用方法的时候传一个数组

        printArray(new int[3]);
        System.out.println("========");
        // 也可以这样写
        printArray(new int[]{100,200,300,400});
    }
    public static void printArray(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
}

main方法上面的“String[] args”有什么用?JVM负责调用main方法,程序员负责写main方法,JVM负责调用该方法
JVM调用main方法的时候,会自动传一个String数组:

public class ArrayTest {
    public static void main(String[] args) {
        System.out.println("JVM传递过来的String参数数组的长度:" + args.length);// 0
    }
}

可以看到,数组对象创建了,但是数组中没有任何数据。其实这个数组是留给用户的,用户可以在控制台上输入参数,这个参数会自动被转换为“String[] args”。例如这样运行java程序:java ArrayTest abc def xyz,JVM会自动将“abc def xyz”通过空格的方式分离,分离完成之后,自动放到“String[] args”数组中。那么你可以自己试一下

public class ArrayTest {
    public static void main(String[] args) {
        System.out.println("JVM传递过来的String参数数组的长度:" + args.length);// 0
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
    }
}

数组中存储的类型为引用数据类型:

public class ArrayTest {
    public static void main(String[] args) {
       // 创建一个Animal数组
        Animal animal1 = new Animal();
        Animal animal2 = new Animal();

        Animal[] animals = {animal1, animal2};
        // 对Animal数组遍历
        for (int i = 0; i < animals.length; i++) {
            Animal a = animals[i];
            a.move();
        }
        // Animal数组不能存放Animal类型,不能存放Product类型
        // animals[2] = new Product();

        // Animal可以存放Dog类型数据,因为Dog是Animal的子类
        // 在这里数组不可以直接扩容的
        // 所以修改最后一个元素的值 为Dog类型
        animals[1] = new Dog();
        for (int i = 0; i < animals.length; i++) {
            animals[i].move();
        }
        
    }
}
// 动物类
class Animal{
    public void move(){
        System.out.println("Animal moving....");
    }
}
// 商品类
class Product{}
// 狗类
class Dog extends Animal{
    public void move(){
        System.out.println("Dog eating bone.....");
    }
}
public class ArrayTest {
    public static void main(String[] args) {
       // 创建一个Animal数组
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        Animal[] animals = {animal1, animal2};
        for (int i = 0; i < animals.length; i++) {
            // 这里取出来的可能是Dog,Cat,但都属于Animal
            // 如果调用的方法是父类中存在的方法不需要向下转型
            // 直接使用父类型引用调用
            // Animal a = animals[]i;
            // a.move();
            
            // 调用子对象特有的方法,需要向下转型
            if(animals[i] instanceof Dog){
                Dog d = (Dog)animals[i];
                d.eatBone();
            }else {
                Cat c = (Cat)animals[i];
                c.eatFish();
            }

        }
    }
}
// 动物类
class Animal{
    public void move(){
        System.out.println("Animal moving....");
    }
}
// 狗类
class Dog extends Animal{
    public void move(){
        System.out.println("汪汪汪....");
    }
    // 狗特有的方法
    public void eatBone(){
        System.out.println("狗在吃骨头");
    }
}
// 猫类
class Cat extends Animal{
    public void move(){
        System.out.println("喵喵喵....");
    }
    // 猫特有的方法
    public void eatFish(){
        System.out.println("猫会吃鱼");
    }
}

一维数组扩容和拷贝

在java开发中,数组的长度一旦确定不可变,如果想要进行数组扩容,需要先建一个大容量的数组,然后再将小容量数组中的数组一个一个拷贝到大数组中去,所以数组扩容效率较低,涉及到拷贝,所以再开发中尽量少的进行数组的拷贝。

public class ArrayTest {
    public static void main(String[] args) {
        // 拷贝源
        int[] array1 = {1,22,11,33,44};
        // 拷贝目标(拷贝到这个目标数组上)
        int[] array2 = new int[20];

        // 源,源数组的起点,目标数组,目标数组起点,拷贝长度
        System.arraycopy(array1, 1, array2, 2,2);
        // 遍历目标数组
        for (int i = 0; i < array2.length; i++) {
            System.out.println(array2[i]); // 0 0 22 11 0 ...

        }
       // 将array1全部拷贝到array2
       // System.arraycopy(array1,0,array2,0,array1.length);
    }
}

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Java 一维数组概述 一维数组扩容和拷贝》 发布于2020-08-12

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

1 + 4 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册