Java数组基本知识

数组

1 数组概述

  • Java语言中的数组是一种引用类型。不属于基本数据类型。数组的父类是Object。

  • 数组实际上是一个容器,可以同时容纳多个元素。(数组是一个数据的集合。) 数组:字面意思是”一组数据“。

  • 数组当中可以存储”基本数据类型“的数据,也可以存储”引用类型“的数据。

  • 数组因为是引用类型,所以数组对象是堆内存当中。(数组是存储在堆当中的)。

  • 数组当中如果存储的是”Java对象“的话,实际上存储的是对象的”引用(内存地址)“。

  • 数组一旦创建,在Java中规定,长度不可变。(数组长度不可变)。

  • 数组的分类:一维数组、二维数组、三维数组、多维数组…

  • 所有的数组对象都有length属性,用来获取数组中元素的个数。

  • Java中的数组要求数组中的元素类型统一。

  • 数组在内存方面存储的时候,数组中的元素内存地址是连续的。

  • 数组中首元素的内存地址作为整个数组对象的内存地址。

  • 数组这种数据结构的优点和缺点是什么?

    优点:查询/查找/检索某个下标的元素时效率极高。可以说是查询效率最高的一个数据结构。

    为什么检索效率高?

    1. 每个元素的内存地址在空间存储上是连续的。

    2. 每个元素的类型相同,所以占用空间大小一样。

    3. 知道第一个元素内存地址,知道每个元素占用空间的大小,又知道下标,所以通过一个数字表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位元素,所以数组的检索效率是最高的。

      数组中存储100个元素,或者存储100万个元素,在元素查询/检索方面,效率是相同的,因为数组中元素查找的时候不会一个一个找个,是通过数学表达式计算出来的。(算出一个内存地址,直接定位的。)

    缺点:

    ​ 第一:由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或增加元素的时候,效率较低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的操作

    ​ 第二:数组不能存储大数据量,为什么?

    ​ 因为很难在内存空间上找到一块特别大的连续的内存空间。

    注意:对于数组中最后一个元素的增删,是没有效率影响的。

2 一维数组

2.1 怎么初始化一个一维数组?

​ 两种方式:静态初始化、动态初始化

2.1.1 静态初始化
//静态初始化语法格式:
int [] array = {10,20,300,40};
//动态初始化语法格式:
int [] array = new int[5];//这里的5表示数组的元素个数。
						//初始化一个5个长度的int类型数组,每个元素默认值为0
String [] str = new String[6]; //初始化6个长度的String类型数组,每个元素默认值为null。

示例:数组的存取操作

/**
 * @author wcs
 * @date 2021/7/30 21:09
 */
public class ArrayTest01 {
    public static void main(String[] args) {
        int[] a = {1,23,54,56,76};
        //取(读)
        System.out.println("数组的第一个元素"+a[0]);
        System.out.println("数组的最后一个元素"+a[4]);
        System.out.println("数组的最后一个元素"+a[a.length-1]);
        //存(改)
        a[0] = 99;
        a[a.length-1] = 0;
        System.out.println("数组的第一个元素"+a[0]);
        System.out.println("数组的最后一个元素"+a[a.length-1]);
    }
}

运行结果:

image-20210731093341037

一维数组遍历

/**
 * @author wcs
 * @date 2021/7/31 9:39
 */
public class ArrayTest02 {
    public static void main(String[] args) {
        int[] a = {12,23,45,67,875};
        //循环遍历输出
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]);
        }
        //5超过了数组元素总个数,下标越界,出现异常。
       // System.out.println(a[5]);//ArrayIndexOutOfBoundsException(下标越界异常)

        //反向遍历输出
        for (int i = a.length-1; i >= 0; i--) {
            System.out.println(a[i]);
        }
    }
}
2.1.2 动态初始化
/**
 * @author wcs
 * @date 2021/7/31 9:57
 */
public class ArrayTest03 {
    public static void main(String[] args) {
        //动态初始化
        
        //int类型数组元素默认值为0
        int[] a = new int[4];
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]); 
        }
        
        //引用数据类型数组默认值为null
        String [] str = new String[4];
        for (int i = 0; i < str.length; i++) {
            System.out.println(str[i]); 
        }
        Object[] obj = new Object[4];
        for (int i = 0; i < obj.length; i++) {
            System.out.println(obj[i]);
        }
        
        //静态初始化Object类型数组
        Object obj1 = new Object();
        Object obj2 = new Object();
        Object obj3 = new Object();
        Object[] objs ={obj1,obj2,obj3};
        for (int i = 0; i < objs.length; i++) {
            System.out.println(objs[i]);
        }
    }
}
2.1.3 什么时候用静态初始化方式,什么时候用动态初始化方式?

​ 当你创建数组的时候,确定数组中存储哪些具体元素时,采用静态初始化方式。

​ 当你创建数组的时候,不确定将来数组中存储哪些数据,你可以采用动态初始化方式,预先分配内存。

当一个方法的参数是一个数组的时候

/**
 * @author wcs
 * @date 2021/7/31 10:21
 */
public class ArrayTest04 {
    public static void main(String[] args) {
        //静态初始化一维数组
        int[] a = {1,23,45,27};
        printArray(a);
       // printArray({1,2,45,6}); //错误写法
        //如果直接传递一个静态数组的话,必须这样写
        printArray( new int[]{0, 23, 45, 68});
        //动态初始化一维数组
        int[] a2 = new int[4];
        printArray(a2);
        System.out.println("-------------");
        printArray(new int[4]);//也可以这样写
    }
    public static void printArray(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
}

2.2 main方法中的String数组

main方法上面的"String[] args"有什么用?

​ 谁负责调用main方法(JVM),JVM调用main方法的时候,会自动传一个String数组过来。JVM给传递过来的String数组参数,这个数组的长度是0。 args不是null。

String[] strs = {};//静态初始化数组,里面没东西。
System.out.println(str.Length);//0
2.2.1 main方法中String数组案例
/**
 * @author wcs
 * @date 2021/8/4 10:46
 */
public class ArrayTest05 {
    //在run下面的Edit Configurations中Program arguments输入用户名和密码
    //用户名和密码输入到String[] args数组当中。
    public static void main(String[] args) {
        if (args.length != 2){
            System.out.println("请输入用户名和密码");
            return;
        }
        //执行到此说明用户已经输入了用户名或密码。
        //取出判断
        String username = args[0];
        String password = args[1];
        //if(username.equals("admin"))之所以没有这样写是为了防止空指针异常。
        if ("admin".equals(username) && "123".equals(password)){
            System.out.println("欢迎您 "+username);
        }else {
            System.out.println("用户名或密码错误");
        }
    }
}

2.3 数组扩容

在Java程序中,数组长度一旦确定不可变,那么数组满了怎么办?

数组满了,需要扩容。

数组的扩容是:先建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大数组当中。

数组扩容效率较低。尽量避免数组扩容,可以在创建数组的时候预估计容量。

2.4 数组拷贝

//System.arraycopy(5个参数);
//拷贝源,源起始位置下标,拷贝目标,目标的起始下标,拷贝长度。

示例:

import java.util.Arrays;

/**
 * @author wcs
 * @date 2021/8/4 14:53
 */
public class ArrayTest06 {
    public static void main(String[] args) {
        int[] a = {1, 34, 56, 78, 4};
        int[] b = new int[10];
        //从数组a下标为1的位置开始拷贝到数组b下标为2的位置,共拷贝4个元素。
        System.arraycopy(a, 1, b, 2, 4);
        for (int i = 0; i < b.length; i++) {
            System.out.println(b[i]);
        }
    }
} 

运行结果:

image-20210804150536882

3 二维数组

二维数组其实是一个特殊的一维数组,特殊在这个一维数组当中的每一个元素是一个一维数组。

int[] a = {1,23,4};
int[] b = {34,578,5};
int[] c = {56,8,4,2};
//二维数组  静态初始化
int[][] aa = {{1,23,4},{34,578,5},{56,8,4,2}};
//动态初始化
int[][] bb = new int[2][3];

3.1 二维数组的Length属性

public class ArrayTest07 {
    public static void main(String[] args) {
        int[][] aa = {{1,23},{34,578,5},{56,8,4,2}};
        System.out.println(aa.length);//3
        System.out.println(aa[0].length);//2
        System.out.println(aa[2].length);//4
    }
}

3.2 关于二维数组中元素的读和改

/**
 * @author wcs
 * @date 2021/8/4 16:04
 */
public class ArrayTest08 {
    public static void main(String[] args) {
        int[][] aa = {{1,23},{34,578,5},{56,8,4,2}};
        //取出第一个一维数组
        int[] a = aa[0];
        //取出第一个一维数组中的第一个元素
        int x = a[0];
        System.out.println(x);//1
        //合并以上代码
        System.out.println(aa[0][0]);//1
        
                //改
        aa[0][0] = 1111;
        System.out.println(aa[0][0]);

    }
}

3.3 遍历二维数组

/**
 * @author wcs
 * @date 2021/8/4 16:12
 */
public class ArrayTest09 {
    public static void main(String[] args) {
        String[][] strs = {
                {"张三","李四","王二"},
                {"Java","php","c++"},
                {"Jack","rose","okk"}
        };
        //遍历二维数组
        for (int i = 0; i < strs.length; i++) {
            //一层循环二维数组里面的一维数组
            String[] str1 = strs[i];
            //二层循环一维数组中的元素
            for (int j = 0; j < str1.length; j++) {
                System.out.print(str1[j]+" ");
            }
            System.out.println();//换行
        }

        //合并代码
        for (int i = 0; i < strs.length; i++) {
            for (int j = 0; j < strs[i].length; j++) {
                System.out.print(strs[i][j]+" ");
            }
            System.out.println();
        }
    }
}

4 Array工具类

4.1 sort()

import java.util.Arrays;

/**
 * @author wcs
 * @date 2021/8/4 16:30
 */
public class ArrayTest10 {
    public static void main(String[] args) {
        //工具类当中的方法大部分都是静态的
        int[] arr = {23, 47, 223, 112, 34, 5};
        Arrays.sort(arr);//升序
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

4.2 fill()

import java.util.Arrays;

/**
 * @author wcs
 * @date 2021/8/4 20:44
 */
public class ArrayTest13 {
    public static void main(String[] args) {
        int[] a = new int[10];
        Arrays.fill(a, 11);
        System.out.println(Arrays.toString(a));
        
        //填充数组,从哪个下标开始,到哪个下标位置,填充数据
        Arrays.fill(a, 3, 8, 4);
        System.out.println(Arrays.toString(a));
    }
}

4.3 比较数组

import java.util.Arrays;

/**
 * @author wcs
 * @date 2021/8/4 20:51
 */
public class ArrayTest14 {
    public static void main(String[] args) {
        String[] str1 = {"Java", "php", "c++"};
        String[] str2 = {"Java", "php", "c++"};
        System.out.println(Arrays.equals(str1, str2));//true
    }
}

4.4 数组转字符串

//一维数组
int[] a = {2,43,21,33,29};
        //数组转字符串
        System.out.println(Arrays.toString(a));//[2, 43, 21, 33, 29]

//多维数组
int[][][] b = {
                {{23, 1, 34, 2}},
                {{44, 55, 66}},
                {{99, 0, 54, 28}},
                {{17, 98, 45}}
        };
        System.out.println(Arrays.deepToString(b));
//[[[23, 1, 34, 2]], [[44, 55, 66]], [[99, 0, 54, 28]], [[17, 98, 45]]]

5 冒泡排序

import java.util.Arrays;

/**
 * @author wcs
 * @date 2021/8/4 20:07
 */

/**
 * 冒泡排序,
 * 	由小到大
 * 	从前向后两两比较,如果前面的数大于后面的数就交换
 * 	如果有n个数,需要比较n-1轮
 */
public class ArrayTest11 {
    public static void main(String[] args) {
        int[] a = {2, 32, 11, 34, 0, 27};
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    int temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                }
                System.out.println(Arrays.toString(a));
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值