《Java编程思想》数组基础知识

来源:互联网 发布:知之阅读安卓 编辑:程序博客网 时间:2024/05/17 08:41

总的来说这篇文章比较简单。

数组到底和其他的容器有什么不同

1.数组是一个线性序列,这使得数组的访问非常的快速,当然数组的灵活性也比不上ArrayList但是实现ArrayList这样的弹性的开销非常的大,所以其速度远远比不上数组。
2.容器使用的泛型导致容器很多时候必须面临运行时检查,但是数组对于类型的检查却总是在编译期。
下面用一段代码来展示一下两者的区别与联系:

import java.util.*;import static net.mindview.util.Print.*;class BerylliumSphere{    private static long counter;    private final long id = counter++;    public String toString(){        return "Sphere " + id;    }}public class ContainerComparison{    public static void main(String[] args){        BerylliumSphere[] spheres = new BerylliumSphere[10];        for(int i=0; i<5; i++){            spheres[i] = new BerylliumSphere();        }        print(Arrays.toString(spheres));        //输出:[Sphere 5, Sphere 6, Sphere 7, Sphere 8, Sphere 9]        print(spheres[4]);        //输出:Sphere 9        List<BerylliumSphere> sphereList =                 new ArrayList<BerylliumSphere>();        for(int i=0; i<5; i++){            sphereList.add(new BerylliumSphere());        }        print(sphereList);        //输出:[Sphere 2, Sphere 2, Sphere 2, Sphere 2, Sphere 2]        print(sphereList.get(4));        //输出:Sphere 2        int[] integers = {0,1,2,3,4,5};        print(Arrays.toString(integers));        //输出:[0, 1, 2, 3, 4, 5]        print(integers[4]);        //输出:4        List<Integer> intList = new ArrayList<Integer>(                Arrays.asList(0,1,2,3,4,5));        intList.add(97);        print(intList);        //输出:[0, 1, 2, 3, 4, 5, 97]        print(intList.get(4));        //输出:4    }}

可以发现起码数组和ArrayList的区别并不大。

数组是个第一级对象

先上代码:

import java.util.*;import static net.mindview.util.Print.*;class BerylliumSphere{    private static long counter;    private final long id = counter++;    public String toString(){        return "Sphere " + id;    }}public class ArrayOptions{    public static void main(String[] args){        BerylliumSphere[] a;        BerylliumSphere[] b = new BerylliumSphere[5];        print("b: " + Arrays.toString(b));        //输出:b: [null, null, null, null, null]        BerylliumSphere[] c = new BerylliumSphere[4];        for(int i=0; i<c.length; i++){            if(c[i] == null) c[i] = new BerylliumSphere();        }        BerylliumSphere[] d = {new BerylliumSphere(),                new BerylliumSphere(), new BerylliumSphere()                };        a = new BerylliumSphere[]{                new BerylliumSphere(),new BerylliumSphere(),                };//请注意a最后还有一个小逗号        print("a.length = " + a.length);        //输出:a.length = 2,可见后面的小逗号并没有增加a数组的长度        print("b.length = " + b.length);        //输出:b.length = 5,空引用也算引用,如果想要打印出具体类的名称必须要在指定索引位置创建对象        print("c.length = " + c.length);        //输出:c.length = 4        print("d.length = " + d.length);        //输出:d.length = 3        a = d;        print("a.length = " + a.length);        int[] e;        int[] f = new int[5];        print("f:"+Arrays.toString(f));        //输出:f:[0, 0, 0, 0, 0],当没有明确数组中的元素时,默认为0        int[] g = new int[4];        for(int i=0; i<g.length; i++){            g[i] = i*i;        }        int[] h = { 11,47,93};//可以理解为直接引用一个现有的数组        //print("e.length = " + e.length);        //因为e现在是一个空引用,所以不能对其使用方法        print("f.length = " + f.length);        //输出:f.length = 5        print("g.length = " + g.length);        //输出:g.length = 4,同33行        print("h.length = " + h.length);        //输出:h.length = 3        e = h;        print("e.length = " + e.length);        //输出:e.length = 3        e = new int[]{1,2};//创建一个新的数组,可以看到此时不需要指明长度        print("e.length = " + e.length);        //输出:e.length = 2    }}

对上面的代码有几个需要说明的地方:
第一个是数组大小的问题:

int[] i = new int[5];print(i.length);//5

length只能代表数组能够容纳某个特定类型的容量,但并不知道到底有多少元素在数组中。
第二个是数组初始值的问题

int[] a = new int[2];char[] b = new char[2];boolean[] c = new boolean[2];print(Arrays.toString(a));//[0, 0]print(Arrays.toString(b));//[ , ]两个空格print(Arrays.toString(c));//[false, false]

第三个是数组的创建

int[] a1 = new int[5];Object[] a2 = new Object[5];int[] b1 = {1};int[] b2 = {1,};//特别需要注意这里b2的数组长度为1Object[] b3 = {new Object()};Object[] b4 = {1};//这里是由于自动装箱的原因,1转型为Integer然后又向上转型为ObejctObject[] d;d = new Object[]{new Object()};//这里可以和b数组的创建进行比较

当引用同一个数组时

int[] a = {1,2,3};int[] b;b = a;b[1] = 5;print(Arrays.toString(a));//[1, 5, 3]print(Arrays.toString(b));//[1, 5, 3]

b=a就意味着b获得了a的引用,此时修改b也会修改a。

将数组返回

这个很简单,直接上代码

import java.util.*;public class IceCream{    private static Random rand = new Random(47);      static final String[] FLAVORS = {        "Chocolate", "Strawberry", "Vanilla Fudge Swirl",        "Mint Chip", "Mocha Almond Fudge", "Rum Raisin",        "Praline Cream", "Mud Pie"      };      public static String[] flavorSet(int n){          if(n > FLAVORS.length)              throw new IllegalArgumentException("Set too big");          String[] results = new String[n];          boolean[] picked = new boolean[FLAVORS.length];          for(int i=0; i<n; i++){              int t;              do{                  t = rand.nextInt(FLAVORS.length);              }while(picked[t]);              results[i] = FLAVORS[t];              picked[t] = true;          }          return results;      }      public static void main(String[] args){          for(int i=0; i<7; i++){              System.out.println(Arrays.toString(flavorSet(3)));          }      }}/*输出:[Rum Raisin, Mint Chip, Mocha Almond Fudge][Chocolate, Strawberry, Mocha Almond Fudge][Strawberry, Mint Chip, Mocha Almond Fudge][Rum Raisin, Vanilla Fudge Swirl, Mud Pie][Vanilla Fudge Swirl, Chocolate, Mocha Almond Fudge][Praline Cream, Strawberry, Mocha Almond Fudge][Mocha Almond Fudge, Strawberry, Mint Chip]*/

多维数组

首先是如何创建一个多维数组:

import java.util.*;public class MultidimenssionalPrimitiveArray{    public static void main(String[] args){        int[][] a = {            {1,2,3,},            {4,5,6,}        };        //Array.deepToString()是JavaSE5的方法        System.out.println(Arrays.deepToString(a));    }}/*输出:[[1, 2, 3], [4, 5, 6]]*/

java多维数组的创建如上所示,也不是什么很麻烦的事情,我们也可以用new来创建数组

import java.util.*;public class ThreeDwithNew{    public static void main(String[] args){        int[][][] a = new int[2][2][4];        System.out.println(Arrays.deepToString(a));    }}/*输出:[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]基本类型的数组被自动初始化,对象数组初始化为null*/

在文章开头的一部分我们就已经总结过数组初始化的三种方式,对一维数组可用的方法,同样对多维数组可用。下面介绍一下粗糙数组的概念:数组中构成矩阵的每个向量都具有任意的长度,下面用代码展示一下这个问题:

import java.util.*;public class RaggedArray{    public static void main(String[] args){        Random rand = new Random(47);        int[][][] a = new int[rand.nextInt(7)][][];        for(int i=0; i<a.length; i++){            a[i] = new int[rand.nextInt(5)][];            for(int j=0; j<a[i].length; j++){                a[i][j] = new int[rand.nextInt(5)];            }        }        System.out.println(Arrays.deepToString(a));    }}/*输出:[[], [[0], [0], [0, 0, 0, 0]], [[], [0, 0], [0, 0]], [[0, 0, 0], [0], [0, 0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0], []], [[0], [], [0]]]*/

从上面的代码可以发现,在Java中创建一个多维数组可以是一个动态的过程,并不一定要在一开始使用时就固定好数组的长度,我们可以在后来使用的时候在动态的进行创建,当然不仅仅是基本类型数组可以通过这种方式创建,这种创建方式对于非基本类型的对象数组同样适用:

import java.util.*;public class MultidimensionalObjectArrays {  public static void main(String[] args) {    BerylliumSphere[][] spheres = {      { new BerylliumSphere(), new BerylliumSphere() },      { new BerylliumSphere(), new BerylliumSphere(),        new BerylliumSphere(), new BerylliumSphere() },      { new BerylliumSphere(), new BerylliumSphere(),        new BerylliumSphere(), new BerylliumSphere(),        new BerylliumSphere(), new BerylliumSphere(),        new BerylliumSphere(), new BerylliumSphere() },    };    System.out.println(Arrays.deepToString(spheres));  }} /*输出:[[Sphere 0, Sphere 1], [Sphere 2, Sphere 3, Sphere 4, Sphere 5], [Sphere 6, Sphere 7, Sphere 8, Sphere 9, Sphere 10, Sphere 11, Sphere 12, Sphere 13]]*/

上面的spheres也是粗糙数组。当然我们也可以逐步的构建一个非基本类型的数组:

import java.util.*;public class RaggedArray{    public static void main(String[] args){        Integer[][] a;        a = new Integer[3][];        for(int i=0; i<a.length; i++){            a[i] = new Integer[3];            for(int j=0; j<a[i].length; j++){                a[i][j] = i*j;            }        }        System.out.println(Arrays.deepToString(a));    }}/*输出: [[0, 0, 0], [0, 1, 2], [0, 2, 4]]*/

逐步的构建一个非基本类型的对象数组也是可行的。从上面的代码我们可以看出来,Arrays.deepToString()方法对于基本类型数组和对象数组都适用

自动包装机制用于数组

直接上实例

import java.util.*;public class AutoboxingArrays {  public static void main(String[] args) {    Integer[][] a = { //自动包装      { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },      { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },      { 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 },      { 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 },    };    System.out.println(Arrays.deepToString(a));  }} /*输出:[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80]]*/

非常简单的例子,不用多说,但是我们能不能将Integer自动装箱成int呢?

import java.util.*;public class AutoBoxing {  public static void main(String[] args) {    int[] a = { //自动包装            new Integer(1),new Integer(2),            };    System.out.println(Arrays.toString(a));  }} /*输出:[1, 2]*/

可以看到Integer也可以通过自动包装的机制变成int类型的数组。

原创粉丝点击