java学习笔记29--数组

1.概述
    数组是一组数据的集合,数组中的每个数据被称为元素。在java中,数组也是对象。数组中的元素可以是任意类型(基本类型和引用类),但同一个数组里只能存放类型相同的元素。
    
    数组类型的变量、类类型的变量、接口类型的变量都属于引用类型的变量,这些变量都是可以指向其相应的对象的,那么数组类型的变量指向的就是数组对象。

    之前我们接触到的第一个数组类型变量,应该就是main方法的参数
    public static void main(String[] args){
    
    }
    其中 String[] 就是一个数组类型,args就是这个数组类型的变量,它所指向的数组对象中只能存放String类型的数据。
    注:main方法是由JVM负责调用,那么args所指向的数组对象也是由JVM负责创建并传过来.


    2.声明数组类型变量
    1)数组类型
        8种基本数据类型和3种引用类型,使用这些都可以声明出数组类型
        即:任意类型都可以声明成数组类型,只需要加"[]"即可
        例如:
            基本类型的数组:
            byte[] short[] int[] long[] float[] double[] char[] boolean[]
            
            引用类型的数组:
            //使用类声明出的数组
            Student[]
            //使用接口声明出的数组
            Action[]
            //使用数组声明出的数组(也就是二维数组)
            int[][]
        
        注意:使用X类型声明出的数组,那么将来该数组中就只能存放X类型的数据

    2)数组类型变量
        有俩种形式可以声明数组变量,推荐使用第一种。
        int[] a;
        或者
        int a[];
        
        例如:
        String[] str;
        Student[] students;
        long[] l;

        注:数组类型变量将来是要指向对象的。


    3.创建数组对象
    1)数组对象的长度
        数组的长度是指一个数组对象中可以存放多少个数据(元素)。
        每一个数组对象在被创建的时候,就需要指明其长度是多少,并且该长度一定去的就不能再做修改。
    
    2)数组对象的创建
        创建数组对象使用new关键字即可。
        例如:
        int[] a = new int[4];
        String[] str = new String[1];
        //表示该数组对象中一个数据都存放不了
        char[] c = new char[0];
        
        //编译报错,因为创建数组对象的时候没知道其长度
        long[] v = new long[];
    
    3)获得数组对象的长度
        使用数组对象访问其length属性即可获得该数组的长度
        例如:
        int[] a = new int[4];
        System.out.println(a.length);//4

        注意:对象创建后,数组的长度是不能改变的。
        例如:
        //编译报错
        int[] a = new int[4];
        a.length = 8;

        //编译通过
        //但是这只是又新建了一个数组对象
        //而不是改变原来数组对象的长度
        int[] a = new int[4];
        a = new int[8];

    4.数组对象的初始化及使用
    1)数组对象在内存中的位置
        数组对象也是java中的一种对象,但是和之前使用类创建出的对象还是一定区别的。
        数组对象也存放在内存中的堆区,并且数组对象在堆区中是一块连续的内存空间,这其中的每一小块空间都可以存放我们要保存的一个数据(元素)。那么数组的长度指的其实也就是这个东西。
        注:数据对象其实就是堆区中的一块连续的内存空间
        
    2)数组对象中每个元素位置上的默认值
        数组对象中的默认值和其要保存的数据类型有关
        例如:
            int[] a = new int[4];
            在我们存放数据之前,这四个元素位置上就以及有了默认值了
            整型数组的默认值是        0
            浮点型数组的默认值是    0.0
            布尔类型数组的默认值是    false
            字符类型数组的默认值是    0
            引用类型数组的默认值是    null

    3)数组对象中的元素位置的下标
        由于数组对象在堆区中是一块连续的内存空间,那么我们可以通过连续的下标,找到每一个可以存放数据的元素位置。
        注:下标是从0开始的
        例如:
        //通过下标0 1 2 3可以访问到数组对象中四个元素位置的值
        //整型的默认值是 0
        int[] a = new int[4];
        System.out.println(a[0]);//0
        System.out.println(a[1]);//0
        System.out.println(a[2]);//0
        System.out.println(a[3]);//0
        
        //布尔的默认值是 false
        boolean[] a = new boolean[4];
        System.out.println(a[0]);//false
        System.out.println(a[1]);//false
        System.out.println(a[2]);//false
        System.out.println(a[3]);//false
        
        总结:如果一个数组对象的长度是n,那么这个数组下标的值是[0,n-1],其实n必须大于0


    4)使用数组的下标赋值
        String[] str = new String[3];
        //赋值前:使用循环输出数组中的元素
        for(int i=0;i<str.length;i++){
            System.out.println(str[i]);
        }

        str[0] = "hello";
        str[1] = "world";
        str[2] = "test";

        //赋值后:使用循环输出数组中的元素
        for(int i=0;i<str.length;i++){
            System.out.println(str[i]);
        }

    
    5)特殊形式
        //编译通过
        int[] a1 = new int[]{1,3,5,7,9};
        System.out.println(a1.length);//5
        
        //编译通过
        int[] a2 = {2,4,6,8};
        System.out.println(a2.length);//4
        
        //编译通过
        int[] a4;
        a4 = new int[]{1,2,3};
        System.out.println(a4.length);//3
        
        /*下面俩种情况是错误的创建方式*/

        //编译报错
        int[] a3 = new int[3]{1,2,3};
        
        //编译报错
        int[] a4;
        a4 = {1,2,3};

    6)数组下标越界
        对于一个长度为n的数组对象,它的的下标取值范围是[0,n-1],这里的0和n-1就是这个数组对象的下标边界,使用下标的过程中不能超出这个边界。如果超出那么就会运行报错.
        例如:
        int[] a = new int[4];
        a[4] = 10;
        
        运行后结果:
        Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
            at com.briup.test.ArrayTest.main(ArrayTest.java:7)
    

    7)数组对象的拷贝
        数组对象的长度确定之后便不能修改,但我们可以通过复制数组的内容变通实现改变数组长度。
        在java.lang.System类中提供一个名为arraycopy的方法可以实现复制数组中元素的功能

        //该方法的声明
        public static void arraycopy(Object src, int srcPos,Object dest, int destPos,int length)
        参数1,需要被复制的目标数组
        参数2,从这个数组的那个一个位置开始复制
        参数3,需要把数据复制到的另外的那一个新的数组对象
        参数4,复制到新数组里面哪个位置(从这个位置开始算)
        参数5,复制的目标数组的长度
        
        例如:
            写一个方法,接收一个数组对象,把这个数组对象的长度扩大到原来的2倍并返回。

            public int[] test(int[] a){
                int[] b = new int[a.length*2];
                System.arraycopy(a, 0, b, 0, a.length);
                return b;
            }
        

    8)数组的工具类java.util.Arrays
        由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作.

        1)Arrays类的引入
            该是java.util包中的类,在我们的代码中想使用这个类的话,就必须使用import进行导入.

            在当前类A中,只有java.lang包下的类,以及和当前类A在同一个包下的类,不需要import引入之外,其他所有的包下的类在被使用之前都要import引入.
            例如:
                package com.briup.ch04;
                
                import java.util.Arrays;

                public class Xxx{....}
        
        2)Arrays类中方法的调用
            Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意:是"不用" 而不是 "不能")
            
            例如:
                main:
                    //返回指定元素在数组中的下标位置
                    //如果找不到则返回一个小于0的数
                    int[] a = {1,3,5,7,9};
                    int key = Arrays.binarySearch(a,7);
                    System.out.println(key);//3


        3)Arrays类中常用方法
            toString方法,把数组转换位字符串形式并返回
                例如:
                    int[] a = {1,3,5,7,9};
                    System.out.println(Arrays.toString(a));

                    //输出结果: [1, 3, 5, 7, 9]

            binarySearch方法,在数组中查找指定元素并返回其下标
                例如:
                    int[] a = {1,3,5,7,9};
                    int key = Arrays.binarySearch(a,7);
                    System.out.println(key);

                    //输出结果: 3
                注:
                使用二分搜索法来搜索指定的数组,以获得指定的值。必须在进行此调用之前对数组进行排序(通过sort方法等)。如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个
    
            copyOf方法,复制或者截取指定数组并返回
                例如: 复制
                    int[] a = {1,3,5,7,9};
                    a = Arrays.copyOf(a, 8);
                    System.out.println(Arrays.toString(a));
                    //输出结果: [1, 3, 5, 7, 9, 0, 0, 0]
                
                例如: 截取
                    int[] a = {1,3,5,7,9};
                    a = Arrays.copyOf(a, 2);
                    System.out.println(Arrays.toString(a));
                    //输出结果: [1, 3]

            
            copyOfRange方法,将数组中指定范围复制新数组并返回
                例如:
                    int[] a = {1,3,5,7,9};
                    a = Arrays.copyOfRange(a,1,3);
                    System.out.println(Arrays.toString(a));
                    //输出结果: [3, 5]
            
            equals方法,比较俩个数组是否相等
                例如:
                int[] a = {1,3,5,7,9};
                int[] b = {1,3,5,7,9};
                
                System.out.println(Arrays.equals(a, b));//true
                System.out.println(a==b);//false

                注意:==比较的是引用所指向对象的内存地址
                     Arrays.equals方法比较是俩个数组中的内容
            
            fill方法,用指定值去填充数组对象
                例如:
                    int[] a = {1,3,5,7,9};
                    Arrays.fill(a, 99);
                    System.out.println(Arrays.toString(a));

                    //输出结果:[99, 99, 99, 99, 99]

            sort方法,把数据中的元素进行排序
                例如:
                    int[] a = {3,5,1,9,7};
                    System.out.println("before:\t"+Arrays.toString(a));
                    Arrays.sort(a);
                    System.out.println("after:\t"+Arrays.toString(a));

                    //输出结果:
                    before:    [3, 5, 1, 9, 7]
                    after:    [1, 3, 5, 7, 9]

                
            asList方法,可以把数组转换为List集合。


    5.数组使用例子
    1)求一组值的平均值
        public double getAvg(int[] a){
            double sum = 0;
            for(int i=0;i<a.length;i++){
                sum+=a[i];
            }
            return sum/a.length;
        }

    2)求一组值的最大值
        public int getMax(int[] a){
            int max = a[0];
            for(int i=1;i<a.length;i++){
                if(a[i]>max){
                    max = a[i];
                }
            }
            return max;
        }


    3)冒泡排序
        相邻的俩个元素比较,让值较大的数据逐渐向数组的底部(即朝最后一个元素)移动。

        public void sort(int[] a) {
            for(int i=0;i<a.length-1;i++) {
                for(int j=0;j<a.length-i-1;j++) {
                    if(a[j]>a[j+1]) {
                        int temp = a[j];
                        a[j] = a[j+1];
                        a[j+1] = temp;
                    }
                }
            }
        }


    4)从众多手机号码中抽取一个获奖手机号码
        public String getTel(String[] str) {
            int index = (int)(Math.random()*n.length);
            return str[index];
        }

        注意:Math.random()返回值是[0,1)之间的double类型的随机数

    5)产生四位长度的验证码, 验证码内容为大小写字母或数字组成
        public String getValidateCode() {
            String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            char[] c = s.toCharArray();
            int i1 = (int)(Math.random()*c.length);
            int i2 = (int)(Math.random()*c.length);
            int i3 = (int)(Math.random()*c.length);
            int i4 = (int)(Math.random()*c.length);
            
            return ""+c[i1]+c[i2]+c[i3]+c[i4];
        }

    

    6.二维数组
    既然任何类型都可以声明为数组,那么给数组再加一个[]就得到了二维数组,类似的二维数组再加一个[]就得到三维数组。
    
    假定某个宾馆有三层楼,第一层有4个房间,第二层有3个房间,第三层有5个房间。某一天客户入住情况如下所示:

    第三层:             |null|Tom |Jerry|null|Rose|
    第二层:          |Mary|null|Kevin|  ×      ×
    第一层:          |Mike|Jane|Duke |null|  ×
    
    可以用两维数组来存储各个房间的客人信息。
    String[][] room = new String[3][];
    room[0] = new Stirng[]{"Mike","Jane","Duke",null};
    room[1] = new String[]{"Mary",null,"kevin"};
    room[2] = new String[]{null,"Tom","Jerry",null,"Rose"}


    1)声明并创建二维数组
        //堆区有一块连续的内存空间,里面有3个元素位置
        //每个元素位置中都存放了一个一维数组
        //每个一维数组中都有4个元素位置
        //这个4个元素位置上的值都默认是0
        int[][] a = new int[3][4];
        
        //堆区有一块连续的内存空间,里面有3个元素位置
        //每个元素位置上都只有默认值null
        //将来这3个位置上都是要存放一维数组的
        int[][] a = new int[3][];
        
        //编译报错
        int[][] a = new int[][];


    2)给二维数组赋值
        例如:
        int[][] a = new int[3][4];
        a[0][0] = 10;
        a[0][1] = 10;
        a[0][2] = 10;
        a[0][3] = 10;

        a[1][0] = 20;
        a[1][1] = 20;
        a[1][2] = 20;
        a[1][3] = 20;

        a[2][0] = 30;
        a[2][1] = 30;
        a[2][2] = 30;
        a[2][3] = 30;

        例如:
        int[][] a = new int[3][];
        a[0] = new int[1];
        a[1] = new int[2];
        a[2] = new int[3];

        a[0][0] = 10;

        a[1][0] = 20;
        a[1][1] = 20;

        a[2][0] = 30;
        a[2][1] = 30;
        a[2][2] = 30;
        
    3)特殊情况
        //编译通过
        int[][] a = {
            {1},
            {1,2},
            {1,2,3}
        };
        
        //编译通过
        int[][] a4 = new int[][]{
                {1},{1,2},{1,2,3}
        };

        //编译报错
        int[][] a5 = new int[3][]{
            {1},{1,2},{1,2,3}
        };

    4)二维数组结合循环
        String[][] str = {
            {"test1"},
            {"hello1","hello2"},
            {"world1","world2","world3"}
        };
        
        //循环三次,因为str中有三个元素
        //只不过这三个元素每一个都是个一维数组
        for(int i=0;i<str.length;i++){

            //第一个一维数组中有1个元素,元素是String类型的
            //第二个一维数组中有2个元素,元素是String类型的
            //第三个一维数组中有3个元素,元素是String类型的
            //所以内层循环每次打印的次数是不一样的
            for(int j=0;j<str[i].length;j++){
                System.out.println(str[i][j]);
            }
        }

 

    7.可变参数
    注:只有在JDK1.5或以上版本中可用
    例如:
    public void test(int[] a){
    
    }
    我们调用这个方法的时候,"只能"传入一个int[]类型的参数
    int[] a = {1,2,3};
    t.test(a);

    但是如果使用可变参数:
    public void test(int... a){
    
    }
    
    那么调用的时候传入的参数类型及形式就会比较多样
    int[] a = {1,2,3,4};
    t.test2(a);
    t.test2();
    t.test2(1);
    t.test2(1,2,3,4,5,6,7);
    
    可变参数前面可以加其他参数,但可变参数后面再加其他参数就会报错
    public void test(String msg,int... a){
        
    }
    调用方法:
    int[] a = {1,2,3,4};
    String msg = "hello";
    t.test(msg,a);
    t.test(msg);
    t.test(msg,1);
    t.test(msg,1,2,3,4,5,6,7);
    
    
    注:在方法内部,这个可变参数我们使用的时候直接把它当做数组就可以了
    public void test(int... a){
        System.out.println(a.length);
    }


    8.格式化输出(日期常用)
    注:只有在JDK1.5或以上版本中可用
    // 定义一些变量,用来格式化输出。  
    double d = 345.678;  
    int i = 1234;  

    // "%"表示进行格式化输出,"%"之后的内容为格式的定义。
    // "f"表示格式化输出浮点数。
    System.out.printf("%f", d); //345.678000
    System.out.println();  

    // "9.2"中的9表示输出的长度,2表示小数点后的位数。 注意输出数字前面的空格也是算在长度里的
    System.out.printf("%9.2f", d);//   345.68
    System.out.println();  

    // "+"表示输出的数带正负号。  
    System.out.printf("%+9.2f", d);//  +345.68
    System.out.println();  

    // "-"表示输出的数左对齐(默认为右对齐)。  
    System.out.printf("%-9.4f", d);//345.6780
    System.out.println();  

    // "+-"表示输出的数带正负号且左对齐。  
    System.out.printf("%+-9.3f", d);//+345.678
    System.out.println();  

    // "d"表示输出十进制整数。
    System.out.printf("%d", i);//1234
    System.out.println();  

    // "o"表示输出八进制整数。
    System.out.printf("%o", i);//2322
    System.out.println();  

    // "x"表示输出十六进制整数。  
    System.out.printf("%x", i);//4d2
    System.out.println();  

    // "#x"表示输出带有十六进制标志的整数。  
    System.out.printf("%#x", i);//0x4d2
    System.out.println();  

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值