zoukankan      html  css  js  c++  java
  • Java语言(1)-Java中的数组

    Java中数组的长度在创建时指定,从此就不能改变

    数组中元素的类型可以是任何有效的 Java 类型,包括数组类型。也就是说,Java 支持由数组组成的数组,实现多维数组。Java 不支持其他语言中的矩阵式多维数组。

     

    数组的类型和类一样,也是引用类型。数组的实例和类的实例一样,也是对象。

      如:byte[] arrayOfBytes;   

    数组类型不是类,但数组实例是对象。这意味着,数组从 java.lang.Object 类继承了方 法。数组实现了 Cloneable 接口,而且覆盖了 clone() 方法,确保数组始终能被复制,而且 clone() 方法从不抛出 CloneNotSupportedException 异常。数组还实现了 Serializable 接 口,所以只要数组中元素的类型能被序列化,数组就能被序列化。而且,所有数组都有一 名为 length 的字段,这个字段的修饰符是 public final int,表示数组中元素的数量。

     

    数组的放大转换:因为数组扩展自 Object 类,而且实现了 Cloneable 和 Serializable 接口,所以任何数组类型都能放大转换成这三种类型中的任何一种。而且,特定的数组类型还能放大转换成其他数组类型。如果数组中的元素类型是引用类型 T,而且 T 能指定给类型 S,那么数组类型 T[] 就能指定给数组类型 S[]。注意,基本类型的数组不能放大转换

    //所有数组都是可以复制和序列化的对象

     Object o = arrayOfStrings;

     Cloneable c = arrayOfArraysOfInt;

     Serializable s = arrayOfArraysOfInt[0];

    因为数组类型可以放大转换成另一种数组类型,所以编译时和运行时数组的类型并不总是一样

     

    把引用类型的值存储在数组元素中之前,编译器通常必须插入运行时检查,确保运行时这个值的类型和数组元素的类型匹配。如果运行时检查失败,会抛出 ArrayStoreException 异常。

     

    也支持:int justOne, arrayOfThem[], arrayOfArrays[][];

    如下效果一样:

    public String[][] aas1;   // 推荐使用的Java句法

    public String aas2[][];   // C语言的句法

    public String[] aas3[];   // 令人困惑的混用句法

     

    1、创建数组:

    使用 new 关键字创建数组,就像创建对象一样。数组类型没有构造方法,但创建数组时要指定长度,在中括号里使用非负整数指定所需的数组大小:

    byte[] buffer = new byte[1024];

    使用这种句法创建的数组,每个元素都会自动初始化,初始值和类中的字段默认值相同: boolean 类型元素的初始值是 false,char 类型元素的初始值是 u0000,整数元素的初始 值是 0,浮点数元素的初始值是 0.0,引用类型元素的初始值是 null。

     

    2、数组初始化:

    若想在一个表达式中创建数组并初始化其中的元素,不要指定数组的长度,在方括号后面跟着一对花括号,在花括号里写入一些逗号分隔的表达式。当然了,每个表达式的返回值类型必须能指定给数组元素的类型。创建的数组长度和表达式的数量相等。这组表达式的最后一个后面可以加上逗号,但没必要这么做。例如:

    String[] greetings = new String[] { "Hello", "Hi", "Howdy" };

    int[] smallPrimes = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, };

     

    注意,这种句法无需把数组赋值给变量就能创建、初始化和使用数组。某种意义上,这种创建数组的表达式相当于匿名数组字面量,称之为“匿名初始化程序”。下面是几个示例:

    // 调用一个方法,传入一个包含两个字符串的匿名数组字面量

    String response = askQuestion("Do you want to quit?", new String[] {"Yes", "No"});

    // 调用另一个方法,传入匿名对象组成的匿名数组

    double d = computeAreaOfTriangle(new Point[] {new Point(1,2), new Point(3,4), new Point(3,2) });

     

    如果数组初始化程序是变量声明的一部分,可以省略 new 关键字和元素类型,在花括号里列出所需的元素:

    String[] greetings = { "Hello", "Hi", "Howdy" };

    int[] powersOfTwo = {1, 2, 4, 8, 16, 32, 64, 128};

     

    数组字面量在程序运行时,而不是程序编译时,创建和初始化。例如下述数组字面量:

    int[] perfectNumbers = {6, 28};

    编译得到的 Java 字节码和下面的代码相同:

    int[] perfectNumbers = new int[2];

    perfectNumbers[0] = 6;

    perfectNumbers[1] = 28;

     

    Java 在运行时初始化数组有个重要的推论:数组初始化程序中的表达式可能会在运行时计算,而且不一定非要使用编译时常量。例如:

    Point[] points = { circle1.getCenterPoint(), circle2.getCenterPoint() };

     

    3、使用数组

    使用 a[i] 索引数组,并引用某个元素。其中, i 是整数字面量或计算结果为 int 类型值的表达式。

    数组的索引表达式必须是 int 类型,或能放大转换成 int 的类型:byte、short,甚至是 char。数组的索引显然不能是 boolean、float 或 double 类型。

    数组的 length 字段是 int 类型,所以数组中的元素数量不能超过 Integer.MAX_VALUE。

    如果使用 long 类型的表达式索引数组,即便运行时表达式的返回值在 int 类型的取值范围内,也会导致编译出错。

     

    在 Java 中容易编写错误的索引代码,所以运行时每次访问数组都会做检查,确保得到能预料的结果。如果数组的索引太小或太大,Java 会立即抛出 ArrayIndexOutOfBoundsException 异常。

     

    迭代数组:

    int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };

    int sumOfPrimes = 0;

    for(int i = 0; i < primes.length; i++)    

           sumOfPrimes += primes[i];

    另外一种方式(通过for遍历数组):

    for(int p : primes)

      sumOfPrimes += p;

     

    4、复制数组

    所有数组类型都实现了 Cloneable 接口,任何数组都能调用 clone() 方法复制自己。注意,返回值必须校正成适当的数组类型。不过,在数组上调用 clone() 方法不会抛出CloneNotSupportedException 异常。

    样例:

    int[] data = { 1, 2, 3 };

    int[] copy = (int[]) data.clone();

     

    clone() 方法执行的是浅复制。如果数组的元素是引用类型,那么只复制引用,而不复制引用的对象。因为这种复制是浅复制,所以任何数组都能被复制,就算元素类型没有实现 Cloneable 接口也行。clone()效果如下:

            

    不过,有时只想把一个现有数组中的元素复制到另一个现有数组中。System.arraycopy() 方法的目的就是高效完成这种操作。你可以假定 Java 虚拟机实现会在底层硬件中使用高速块复制操作执行这个方法。

    arraycopy() 方法的作用简单明了,但使用起来有些难度,因为要记住五个参数。第一个参数是想从中复制元素的源数组;第二个参数是源数组中起始元素的索引;第三个参数是目标数组;第四个参数是目标索引;第五个参数是要复制的元素数量。

    就算重叠复制同一个数组,arraycopy() 方法也能正确运行。例如,把数组 a 中索引为 0 的元素删除后,想把索引为 1 到 n 的元素向左移,把索引变成 0 到 n-1,可以这么做:

    System.arraycopy(a, 1, a, 0, n);

     

    5、 多维数组

    int[][] products = new int[10][10];

    在某些语言中,会把这样的数组创建成包含 100 个 int 值的数组,但 Java 不会这样处理。 这行代码会做三件事。

    • 声明一个名为 products 的变量,保存一个由 int[] 类型数组组成的数组。

    • 创建一个有 10 个元素的数组,保存 10 个 int[] 类型的数组。

    • 再创建 10 个数组,每个都由 10 个 int 类型的元素组成。然后把这 10 个新数组指定为前一步创建的数组的元素。这 10 个新数组中的每一个 int 类型元素的默认值都是 0。   

               

    换种方式说,前面的单行代码等效于下述代码:

    int[][] products = new int[10][];  // 保存10个int[]类型值的数组

    等效于

    for(int i = 0; i < 10; i++)        // 循环10次……

         products[i] = new int[10];     // ……创建10个数组

     

    使用 new 关键字创建多维数组时,无需指定所有维度的大小,只要为最左边的几个维度指定大小就行。

    和一维数组一样,多维数组也能使用数组初始化程序初始化,使用嵌套的花括号把数组嵌套在数组中即可。

     

    如果不想声明变量就使用多维数组,可以使用匿名初始化程序句法:

    boolean response = bilingualQuestion(question, new String[][] {{ "Yes", "No" },{ "Oui", "Non" }});

     

    6、Array类

    java.util.Arrays 类中包含很多处理数组的静态实用方法。这些方法中大多数都高度重载, 有针对各种基本类型数组的版本,也有针对对象数组的版本。

    排序和搜索数组时,sort() 和 binarySearch() 方法特别有用。

    equals() 方法用于比较两个数组的内容。

    如果想把数组的内容转换成一个字符串,例如用于调试或记录日志,Arrays.toString() 方法很有用。

    Arrays 类中还包含能正确处理多维数组的方法,例如 deepEquals()、deepHashCode() 和 deepToString()。

     

    ===========================

    前文简单总结回顾:

    1、数组类型变量是引用,数组本身是对象。

    2、数组定义方式:int[] intArray = new[10];

    3、数组初始化:

          方式1:int[] intArray = new int[]{1,2,3,4,5,6,7,8,9,10};

          方式2:int[] intArray = {1,2,3,4,5,6,7,8,9,10};

    4、数字初始化过程是在运行时,而不是编译时。因为数组初始化内容可以需要通过运算得到。

    5、数组作为参数,可以使用匿名化初始化方式。如:func(new int[]{1,2,3,4,5,6,7,8,9,10});

    6、数组使用:

          intArray[i]=1;

          数组索引的最大值通过在定义数组时通过final int legth指定。索引i需要是int类型,或者是可放大转换成int型的类型,如:char、byte、short。比如,如果使用double类型变量作为数组索引,java会报错。

    7、遍历数组

          方式一:

        for(int i = 0; i < intArray.length,i++)

          sum += intArray[i];

          方式二:

        int intNum = 0;

        for(intNum:intArray)

          sum += intNum;

    8、数组复制

      数组支持clone方法,如:int[] intArray2 = (int[])intArray.clone()。注意,clone复制的是数组索引,并不是把数组对象复制一份。

      指定范围复制数组对象内容:  System.arraycopy(sourceArray,sourceStartpos,destArray,destStartPos,copyNum)

      移动同一数组中指定序列到其他位置,也可以使用System.arraycopy()。

    9、多维数组int[][] intArray = new int[10][10];  多维数组的内存保存方式和C语言中不同。

    10、java.util.Arrays类中定义了很多数组的静态操作方法。

     

  • 相关阅读:
    Linux shell脚本基础学习详细介绍(完整版)二
    python读取单个文件操作
    【转载】HTTP 缓存的四种风味与缓存策略
    【转载】HTTP 响应头与状态码
    【转载】HTTP 请求头与请求体
    【转载】HTTP 基础与变迁
    3-2 从单词中获取单词出现的频率信息,并把他们写进对应的列表里
    170925_2 Python socket 创建UDP的服务器端和客户端
    170925_1 Python socket 创建TCP的服务器端和客户端
    2-2 列表推导同 filter 和 map 的比较
  • 原文地址:https://www.cnblogs.com/yickel/p/12783452.html
Copyright © 2011-2022 走看看