数组的学习

数组定义:通过连续的存储空间,存储相同类型的数据集合。

内存存储:有序—》索引:递增有序

存储内容:固定–》随机访问:高效

内存存储结构:吃内存,保证内存连续存储空间够。

元素类型相同:元素所占内存宽度一致,创建对象指向堆的地址,索引从0开始

声明一个变量–变量指向一个数创建出来的数组对象–》对象存储的是当前对象的引用地址。引用的是0索引上的元素地址。

元素的地址=首元素地址+(索引*元素宽度)

/**
 * @author renyuhua
 * @date 2021年09月15日 9:37
 * 1、数组的定义方式
 *      int[] arrs;
 *      String strs[];   不推荐
 * 2、初始化:
 *      静态初始化:
 *          a:
 *              int[] arrs = new int[]{1,2,3};
 *              [I@6d6f6e28   class对象名称+hashcode值
     *              [: 表示是数组类型
     *              I: 表示类型是int
     *              @: 表示打印的地址
     *              6d6f6e28: 表示hashcode值
 *          b:
 *              String[] s = {"数据结构"};
 *      动态初始化:
 *			//声明一个能够存储5个元素的int类型的数组,把当前的数组的引用给向ars这个变量
 *          int[] ars = new int[5];   
 *      常见问题: 
 *          a、声明数组的时候,动态初始化前不指定长度
 *          b、给数字重新赋值的时候,通过{}创建数字对象
 *              int[] ars = new int[5];  ars = {1};  //这里会报编译出错
 *
 */
public class ArrayTest {
    public static void main(String[] args) {

        int[] arrs = new int[]{1,2,3};

        System.out.println(arrs);

        String[] s = {"数据结构"};

        //声明一个数组的时候不循允许  ars = {1};  重新赋值
        int[] ars = new int[5];
        
        ars = new int[]{1,2,3,4};

        System.out.println(ars);


    }
}

数组常见属性

length:

​ 1、数组长度。2、数组存储的元素的个数

​ 2、有序:通过索引可以获取属性、修改属性,从0开始

​ 3、size=length --------------> 0<=索引<=length-1

/**
 * @author renyuhua
 * @date 2021年09月15日 11:00
 * 测试数组的属性:
 *      数组越界异常:通过索引获取数组元素时,超过了索引的范围  [0,length-1]
 */
public class ArrayProperty {
    public static void main(String[] args) {

        // 1、声明一个int类型的数组
        // 数组的长度就会被确定
        int[] array = new int[]{1,2,3};

        // 2、获取当前数组的源数个数,获取当前数组的长度
        System.out.println("当前数组的长度是:"+array.length);

        // 3、通过索引获取指定位置上的元素
        System.out.println("获取索引是2的元素:"+array[1]);

        String[] strings = new String[10];
        System.out.println(strings.length);
         /*
         System.out.println(strings[1]);
        检查信息:报告任何数组字段或变量的内容是读但不写,或写但不读。
        这种不匹配的读和写是没有意义的,可能表示已死的、不完整的或错误的代码。
         */
         
    }
}

对于数组的内存分析
/**
 * @author renyuhua
 * @date 2021年09月15日 11:18
 */
public class ArrayMemory {
    public static void main(String[] args) {

        int[] array = new int[5];
        // 将10赋值给内存中索引是2的元素
        array[2] = 10;
        System.out.println(array.length);
        System.out.println(array[0]);
        System.out.println(array[2]);
        /*
        栈: 存储的是局部变量,后进先出,分配main方法栈,存储array,引用数组对象
        在堆内存中开辟一个长度为5的数组空间,创建数组对象的时候指定长度,当前对位置上的元素都是当前数组对应类型的默认值
        array会指向当前堆内存创建出来的数组的地址,会引用到这个地址,拿到的是当前0索引上的这个元素的地址,根据索引快速获取每一个u元素地址的索引,快速访问到每一个位置对应的当前的元素
        array[2] = 10;   找0索引   元素的地址=首元素地址+(索引*元素宽度)  替换10
        堆: 所有的引用类型的数据都会存在堆内存当中
         */

    }
}

为什么数组是不可变的

数组的长度一旦指定是不可改变的

老数组指向新的数组

array = new int[20];
数组的增删查改以及迭代的方式
import java.util.Arrays;

/**
 * @author renyuhua
 * @date 2021年09月15日 13:17
 * 数组的长度一旦指定无法修改
 * 针对于数组的增删改查
 */
public class ArrayUpdate {
    public static void main(String[] args) {

        int[] array = new int[]{11,44,5,66};

        System.out.println(array[3]);
        array[0] = 10;
        // 遍历数组的输出
        System.out.println(Arrays.toString(array));
        /*
        数组长度不可变,所以给array新增元素只能通过重新开辟空间的方式
         */

        // 删除元素
        array[2] = 0;

        // 普通for循环: [0,array.length)
        for (int i = 0; i < array.length; i++) {
            System.out.println("i:"+array[i]);
            array[i] += 2;
            System.out.println("i+2:"+array[i]);
        }

        System.out.println(Arrays.toString(array));

        // 增强for循环 foreach,无法获取索引,人为指定,将每个元素赋值给num
        int index = 0;
        for (int num : array) {
            System.out.println("foreach:"+index+":"+num);
            index++;
        }

    }
}

多维数组
import java.util.Arrays;

/**
 * @author renyuhua
 * @date 2021年09月16日 9:44
 * 多维数组的创建、初始化、内存分析
 * 在java中存在一维数组和n维数组
 * 二维数组的动态初始化:
 *      type[][] name = new type[m.length][n.length];
 * 就是一个一维数组,只不过每个位置上的元素又是一个一维数组而已。
 */
public class ArrayMultidimensional {
    public static void main(String[] args) {

        // 二维数组的声明
        int[][] arrays = new int[2][3];

        System.out.println(Arrays.toString(arrays[0]));
        System.out.println(arrays[0][1]);

        // 创建了一个一维数组,这个数组的长度是三个,每个数组上都是一个新的一维数组,这个数组的长度是2。
        String[][] strings = new String[][]{{"你好","舟舟"},{"嘿嘿","哈哈"},{"宇华","喜喜"}};
        System.out.println(Arrays.toString(strings[1]));
        // 创建了一个一维数组,这个数组的长度是三个,每个数组上都是一个新的一维数组,这个数组的长度是2。
        String[][] strings1 = {{"你好","舟舟"},{"嘿嘿","哈哈"},{"宇华","喜喜"}};
        System.out.println(Arrays.toString(strings[0]));

        // 创建了一个长度是2的一维数组,每个位置上的元素也是一个数组对象
        int[][] array = new int[2][];
        System.out.println(Arrays.toString(array[0]));
        array[0] = new int[3];
        array[1] = new int[5];
        System.out.println(Arrays.toString(array));
        System.out.println(array[0][1]);
    }
}

二维数组的CRUD迭代
/**
 * @author renyuhua
 * @date 2021年09月16日 10:07
 */
public class ArrayMultUpdate {
    public static void main(String[] args) {

        // 创建的时候需要指定一维数组的长度
        int[][] arrays = new int[3][];

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

        // 二维数组的迭代
        for (int i = 0; i < arrays.length; i++) {
            for (int j = 0; j < arrays[i].length; j++) {
                System.out.println(arrays[i][j]);
            }
            System.out.println();
        }

        // 先遍历一维数组,把每个值迭代到 a,再把a的每个值迭代到 b
        for (int[] a : arrays) {
            for (int b: a ) {
                System.out.println(b);
            }
            System.out.println();
        }
    }
}

关于可变参数–简化开发
/**
 * @author renyuhua
 * @date 2021年09月16日 10:19
 */
public class ArrayVariableParameter {
    public static void main(String[] args) {

        int num1 = 1;
        int num2 = 2;
        add(new int[]{num1,num2});
        adds("",num1,num2);

    }

    public static void add(int[] num){
        int result = 0;
        for (int n : num){
            result += n;
        }
        System.out.println(result);
    }

    /**
     * jdk1.5之后的改变。
     * 可变参数的定义一定要放在末尾。
     * 可变参数一定要保证在形式参数的列表的末尾。
     * 对于参数列表而言,必须要保证形参列表中有且只能有一个可变参数。
     * @param num
     */
    public static void adds(String string,int ... num){
        int result = 0;
        for (int n : num){
            result += n;
        }
        System.out.println(result);
    }
}

关于可变参数的一些坑

最近最优原则

byte–>short–>int–>long–>float–>double(基本数据类型)–>包装类

char–>int

方法的调用顺序:

​ 1、第一匹配顺序完全匹配

​ 2、第二匹配原则最近最优

​ 3、第三匹配顺序包装类

​ 4、第四匹配顺序可变参数

可变参数继承
/**
 * @author renyuhua
 * @date 2021年09月16日 11:24
 * null可以转换为任意的引用类型
 * 避免程序出现二义性
 */
public class ArraySelect {
    public static void main(String[] args) {
        //fun("",null);
    }

    public static void fun(String str,String ... strings){
        System.out.println();
    }

    public static void fun(String str,Integer ... integers){
        System.out.println();
    }
}

关于null值和引用类型的转换关系
/**
 * @author renyuhua
 * @date 2021年09月16日 13:37
 * null值转化为引用类型时,需要注意最近最优。
 */
public class ArrayExchange {
    public static void main(String[] args) {

        // 调用的是第二个invoke方法,null可以转换为任意的引用类型
        // 引用类型: 最近最优,String是Object的子类,null离String更近一些,先找父亲,再找爷爷
        invoke(null,1);
    }

    static void invoke(Object object,Object ... args){
        System.out.println();
    }

    static void invoke(String string,Object object,Object ... args){
        System.out.println();
    }
}

稀疏(矩阵)数组和二维数组的转换
值(元素个数)
151519
原来的二维数组15行,15列,用了19个元素
481
572
现在用行列值区分
/**
 * @author renyuhua
 * @date 2021年09月16日 13:55
 */
public class Convert {
    static int[][] array;
    static {
        array = new int[15][15];
        array[4][8] = 1; array[7][5] = 2; array[5][7] = 2;
        array[7][7] = 1; array[5][8] = 1; array[7][8] = 2;
        array[6][4] = 1; array[7][9] = 2; array[6][6] = 2;
        array[8][7] = 1; array[6][8] = 2; array[8][8] = 2;
        array[6][9] = 1; array[8][9] = 1; array[8][10] = 1;
        array[9][7] = 2; array[9][8] = 2; array[10][6] = 1;
        array[10][8] = 1;
    }

    public static void main(String[] args) {

        System.out.println(toString(array));

        int[][] sparesMatrix = convertSparesMatrix(array);
        System.out.println(toString(sparesMatrix));

        int[][] arrays = convertArray(sparesMatrix);
        System.out.println(toString(arrays));
    }

    private static int[][] convertArray(int[][] sparesMatrix) {
        int[][] arrays = new int[sparesMatrix[0][0]][sparesMatrix[0][1]];
        for (int i = 1; i < sparesMatrix.length; i++) {
            arrays[sparesMatrix[i][0]][sparesMatrix[i][1]] = sparesMatrix[i][2];
        }
        return arrays;
    }


    private static int[][] convertSparesMatrix(int[][] array) {

        // 拿到非0元素的个数
        int noZeroNum = 0;
        for(int[] rows : array) {
            for (int num : rows) {
                if (num!=0){
                    noZeroNum++;
                }
            }
        }

        int[][] sparesMatrix = new int[noZeroNum+1][3];
        // 第一行已经填充了列
        sparesMatrix[0][0] = 15;
        sparesMatrix[0][1] = 15;
        sparesMatrix[0][2] = noZeroNum;

        int noZeroRow = 0;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                if (array[i][j]!=0){
                    noZeroRow++;
                    sparesMatrix[noZeroRow][0] = i;
                    sparesMatrix[noZeroRow][1] = j;
                    sparesMatrix[noZeroRow][2] = array[i][j];
                }
            }
        }

        return sparesMatrix;
    }

    private static String toString(int[][] args){
        StringBuilder ret = new StringBuilder();
        for(int[] rows : args){
            for(int num : rows){
                ret.append(num+"\t");
            }
            ret.append("\r\n");
        }
        return ret.toString();
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值