zoukankan      html  css  js  c++  java
  • Java数组

    Java数组学习

    数组概述

    Java的数组要求所有的数组元素具有相同的数据类型。因此,在一个数组中,数组元素的类型是唯一的,即一个数组里只能存储一种数据类型的数据,而不能存储多种数据类型的数据。

    PS:因为Java语言是面向对象的语言,而类与类之间可以支持继承关系,这样可能产生一个数组里可以存放多种数据类型的假象。例如有一个水果数组,要求每个数组元素都是水果,实际上数组元素既可以是苹果,也可以是香蕉,但这个数组的数组元素的类型还是唯一的,只能是水果类型。

    数组也是一种数据类型,它本身是一种引用类型。例如int是一个基本类型,但int[](这是定义数组的一种方式)就是一种引用类型了。

    数组定义

    type [] arrayName;

    type arraryName[];

    数组是一种引用类型的变量,因此使用它定义一个变量时,仅仅表示定义了一个引用变量(也就是定义了一个指针),这个引用变量还未指向任何有效的内存,因此定义数组时不能指定数组的长度。而且由于定义数组只是定义了一个引用变量,并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素,因此这个数组也不能使用,只有对数组进行初始化后才可以使用。

    数组初始化

    初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值。

    数组的初始化有如下两种方式。

    静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。

    arratName =new type[] {element1,element2...}

    简化写法:arrayName={element1,element2...};

    int [] array =new int [] {5,6,8,0}

    int [] array={5,6,7,8}

    动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值。

    arrayName =new type[length];

    int [] prices =new int[5];

    系统按如下规则分配初始值。

    数组元素的类型是基本类型中的整数类型(byte、short、int和long),则数组元素的值是0。

    数组元素的类型是基本类型中的浮点类型(float、double),则数组元素的值是0.0.

    数组元素的类型是基本类型中的字符类型(char),则数组元素的值是'u0000'。

    数组元素的类型是基本类型中的布尔类型(boolean),则数组元素的值是false。

    数组元素的类型是引用类型(类、接口和数组),则数组元素的值是null。

    数组使用

    System.out.println(arr[1]);

    arr[1]="aaaa";

    如果访问数组元素时指定的索引值小于0,或者大于等于数组的长度,编译程序不会出现任何错误,但运行时出现异常:java.lang.ArrayIndexOutOfBoundsException:N(数组索引越界异常),异常信息后的N就是程序员试图访问的数组索引。

    ForEach循环

    for( type variableName : attay | collention)

    {//variableName 自动迭代访问每个元素

    }

    eg:

    for(String book :books ){
        book="aaa";
        System.out.println(book);
    }
    

    内存中的数组

    数组引用变量只是一个引用,这个引用变量可以指向任何有效的内存,只有当该引用指向有效内存后,才可通过该数组变量来访问数组元素。

    与所有引用变量相同的是,引用变量是访问真实对象的根本方式。也就是说,如果我们希望在程序中访问数组对象本身,则只能通过这个数组的引用变量来访问它

    实际的数组对象被存储在堆(heap)内存中;如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈(stack)内存中。数组在内存中的存储示意图如下图所示。PS(图片来源于传播智客)

    img

    img

    栈内存与堆内存区别:

    当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁。因此,所有在方法中定义的局部变量都是放在栈内存中的;当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(在方法的参数传递时很常见),则这个对象依然不会被销毁。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它。

    当我们看一个数组时,一定要把数组看成两个部分:一部分是数组引用,也就是在代码中定义的数组引用变量;还有一部分是实际的数组对象,这部分是在堆内存里运行的,通常无法直接访问它,只能通过数组引用变量来访问。

    基本类型数组的初始化

    int [] arr;
    arr=new int [5];
    for(int i=0;i<arr.length;i++){
        arr[i]=i+100;
    }
    

    执行第一行内存如下

    文件无法预览。

    执行第二行

    文件无法预览。

    执行for循环

    文件无法预览。

    引用类型数组的初始化

    class person{
        public int age;
        public double height;
        public void info(){
            sout;
        }
    }
    //main中
    Person []stu;
    stu=new Person[2];
    person zhang=new Person();
    zhang.age=18;
    zhang.height=120;
    person li=new Person();
    li.age=14;
    li.height=130;
    stu[0]=zhang;
    stu[1]=li;
    li.info();
    stu[1].info();
    

    执行Person[]stu;代码时,这行代码仅仅在栈内存中定义了一个引用变量,也就是一个指针,这个指针并未指向任何有效的内存区.

    初始化后内存变化

    文件无法预览。

    声明两个Person变量,zhang和li,此时在栈内存中分配两块内存用于存储变量zhang和li,在堆内存中分配两块内存用于存储zhang和li的数据,如下图

    文件无法预览。

    给stu数组赋值后堆内存变化如下:

    文件无法预览。

    多维数组

    二维数组定义

    type [][] arrName;
    

    Java语言采用上面的语法格式来定义二维数组,但它的实质还是一维数组,只是其数组元素也是引用,数组元素里保存的引用指向一维数组。

    接着对这个“二维数组”执行初始化,同样可以把这个数组当成一维数组来初始化,把这个“二维数组”当成一个一维数组,其元素的类型是type[]类型,则可以采用如下语法进行初始化:

    arrName=new type [length][]
    

    工具类

    Java提供的Arrays类里包含的一些static修饰的方法可以直接操作数组,这个Arrays类里包含了如下几个static修饰的方法(static修饰的方法可以直接通过类名调用)。

    int binarySearch(type[]a,type key):使用二分法查询key元素值在a数组中出现的索引;如果a数组不包含key元素值,则返回负数。调用该方法时要求数组中元素已经按升序排列,这样才能得到正确结果。

    int binarySearch(type[]a,int fromIndex,int toIndex,type key):这个方法与前一个方法类似,但它只搜索a数组中fromIndex到toIndex索引的元素。

    type[]copyOf(type[]original,int newLength):这个方法将会把original数组复制成一个新数组,其中length是新数组的长度。如果length小于original数组的长度,则新数组就是原数组的前面length个元素;如果length大于original数组的长度,则新数组的前面元素就是原数组的所有元素,后面补充0(数值类型)、false(布尔类型)或者null(引用类型)。

    type[]copyOfRange(type[]original,int from,int to):这个方法与前面方法相似,但这个方法只复制original数组的from索引到to索引的元素。

    boolean equals(type[]a,type[]a2):如果a数组和a2数组的长度相等,而且a数组和a2数组的数组元素也一 一相同,该方法将返回true。

    void fill(type[]a,type val):该方法将会把a数组的所有元素都赋值为val。

    void fill(type[]a,int fromIndex,int toIndex,type val):该方法与前一个方法的作用相同,区别只是该方法仅仅将a数组的fromIndex到toIndex索引的数组元素赋值为val。

    void sort(type[]a):该方法对a数组的数组元素进行排序。

    void sort(type[]a,int fromIndex,int toIndex):该方法与前一个方法相似,区别是该方法仅仅对fromIndex到toIndex索引的元素进行排序。

    String toString(type[] a):该方法将一个数组转换成一个字符串。该方法按顺序把多个数组元素连缀在一起,多个数组元素使用英文逗号(,)和空格隔开。

    作者:Loserfromlazy
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    数据一致性
    linux下关于程序性能和系统性能的工具、方法
    关于网站架构的一些文章
    列出man手册所有函数的方法
    dup和dup2函数以及管道的实现
    knowledge about apache
    第三篇 读后感
    课程作业02
    《大道至简》第二篇读后感
    课程作业01
  • 原文地址:https://www.cnblogs.com/yhr520/p/12658474.html
Copyright © 2011-2022 走看看