`

第16章数组

 
阅读更多
1.数组和其他容器相比是一种效率最高的存储和随机访问对象的方式,但是它的缺点是大小被固定。

2.数组可以持有基本类型,而泛型之前的容器则不能

3.无论使用什么类型的数组,数组标识符其实只是一个引用,指向在堆中创建的一个真实对象,这个对象用于保存指向其他对象的引用。对象数组和基本类

型数组在使用上几乎是相同的,唯一的区别就是对象数组保存的是引用,基本类型数组保存基本类型的值。下面是数组的各种初始化方法:

public class ArrayOptions {
  public static void main(String[] args) {
    // Arrays of objects:
    BerylliumSphere[] a; // Local uninitialized variable局部初始化
    BerylliumSphere[] b = new BerylliumSphere[5];
    // The references inside the array are
    // automatically initialized to null:
    print("b: " + Arrays.toString(b));
    BerylliumSphere[] c = new BerylliumSphere[4];
    for(int i = 0; i < c.length; i++)
      if(c[i] == null) // Can test for null reference
        c[i] = new BerylliumSphere();
    // Aggregate initialization:采用的是聚集初始化语法来初始化数组
    BerylliumSphere[] d = { new BerylliumSphere(),
      new BerylliumSphere(), new BerylliumSphere()
    };
    // Dynamic aggregate initialization:这是动态聚集初始化。上面的必须在必须在定义出使用。动态聚集初始化就没有这个限制
    a = new BerylliumSphere[]{
      new BerylliumSphere(), new BerylliumSphere(),
    };
    // (Trailing comma is optional in both cases)
    print("a.length = " + a.length);
    print("b.length = " + b.length);
    print("c.length = " + c.length);
    print("d.length = " + d.length);
    a = d;
    print("a.length = " + a.length);

    // Arrays of primitives:
    int[] e; // Null reference
    int[] f = new int[5];
    // The primitives inside the array are
    // automatically initialized to zero:
    print("f: " + Arrays.toString(f));
    int[] g = new int[4];
    for(int i = 0; i < g.length; i++)
      g[i] = i*i;
    int[] h = { 11, 47, 93 };
    // Compile error: variable e not initialized:
    //!print("e.length = " + e.length);
    print("f.length = " + f.length);
    print("g.length = " + g.length);
    print("h.length = " + h.length);
    e = h;
    print("e.length = " + e.length);
    e = new int[]{ 1, 2 };
    print("e.length = " + e.length);
  }
} /* Output:
新生成一个对象数组时,其中所有的引用都被自动化为null,所以检查其中的引用是否为null,即可知道数组的某个位置是否存有对象。同样,基本类型的

数组如果是数值类型,被自动初始化为0,如果是字符型,被自动化为(char)O;如果是boolean,自动初始化为false。

4.数组有个字段length,表示数组能够存储多少元素。

5.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;
}
注意上面的实现,随机选择,确保返回的数组中没有重复的元素。

6.多维数组创建很方便,例如:
public class MultidimensionalPrimitiveArray {
  public static void main(String[] args) {
    int[][] a = {
      { 1, 2, 3, },
      { 4, 5, 6, },
    };
    System.out.println(Arrays.deepToString(a));//该方法可以将多维数组转换成多个String
  }
}

数组中构成矩阵的每个向量都可以具有任意的长度(这被称为粗糙数组):
public class RaggedArray {
  public static void main(String[] args) {
    Random rand = new Random(47);
    // 3-D array with varied-length vectors:
    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));
  }
}
也可以用花括号来初始化:
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));
  }
}

7.使用参数化方法而不是使用参数化类的好处是,不必为需要应用的每种不同的类型都使用一个参数去实例化这个类。当然,不能总是选择参数化方法而不

是参数化类,但是它是首选:
class ClassParameter<T> {
  public T[] f(T[] arg) { return arg; }
}

class MethodParameter {
  public static <T> T[] f(T[] arg) { return arg; }
}

public class ParameterizedArrayType {
  public static void main(String[] args) {
    Integer[] ints = { 1, 2, 3, 4, 5 };
    Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 };
    Integer[] ints2 =
      new ClassParameter<Integer>().f(ints);
    Double[] doubles2 =
      new ClassParameter<Double>().f(doubles);
    ints2 = MethodParameter.f(ints);
    doubles2 = MethodParameter.f(doubles);
  }
}

8.不能创建泛型数组这一说法并不十分准确。例如:
public class ArrayOfGenerics {
  @SuppressWarnings("unchecked")
  public static void main(String[] args) {
    List<String>[] ls;
    List[] la = new List[10];
    ls = (List<String>[])la; // "Unchecked" warning
    ls[0] = new ArrayList<String>();
    // Compile-time checking produces an error:
    //! ls[1] = new ArrayList<Integer>();

    // The problem: List<String> is a subtype of Object
    Object[] objects = ls; // So assignment is OK
    // Compiles and runs without complaint:
    objects[1] = new ArrayList<Integer>();

    // However, if your needs are straightforward it is
    // possible to create an array of generics, albeit
    // with an "unchecked" warning:
    List<BerylliumSphere>[] spheres =
      (List<BerylliumSphere>[])new List[10];
    for(int i = 0; i < spheres.length; i++)
      spheres[i] = new ArrayList<BerylliumSphere>();
  }
} ///:~

可以看到,数组元素可以参数化。

9.注意这种用法:
public class ArrayOfGenericType<T> {
  T[] array; // OK
  @SuppressWarnings("unchecked")
  public ArrayOfGenericType(int size) {
    //! array = new T[size]; // Illegal
    array = (T[])new Object[size]; // "unchecked" Warning
  }
  // Illegal:
  //! public <U> U[] makeArray() { return new U[10]; }
}

10

import java.util.Arrays;

public class FillingArrays {
public static void main(String[] args) {
int size = 6;
boolean[] a1 = new boolean[size];
byte[] a2 = new byte[size];
char[] a3 = new char[size];
short[] a4 = new short[size];
int[] a5 = new int[size];
long[] a6 = new long[size];
float[] a7 = new float[size];
double[] a8 = new double[size];
String[] a9 = new String[size];
Arrays.fill(a1, true);
System.out.println("a1 = " + Arrays.toString(a1));
Arrays.fill(a2, (byte) 11);
System.out.println("a2 = " + Arrays.toString(a2));
Arrays.fill(a3, 'x');
System.out.println("a3 = " + Arrays.toString(a3));
Arrays.fill(a4, (short) 17);
System.out.println("a4 = " + Arrays.toString(a4));
Arrays.fill(a5, 19);
System.out.println("a5 = " + Arrays.toString(a5));
Arrays.fill(a6, 23);
System.out.println("a6 = " + Arrays.toString(a6));
Arrays.fill(a7, 29);
System.out.println("a7 = " + Arrays.toString(a7));
Arrays.fill(a8, 47);
System.out.println("a8 = " + Arrays.toString(a8));
Arrays.fill(a9, "Hello");
System.out.println("a9 = " + Arrays.toString(a9));
// Manipulating ranges:
Arrays.fill(a9, 3, 5, "World");
System.out.println("a9 = " + Arrays.toString(a9));
}
}

Arrays类的fill方法
fill

public static void fill(boolean[] a,
                        boolean val)

    Assigns the specified boolean value to each element of the specified array of booleans.

    Parameters:
        a - the array to be filled.
        val - the value to be stored in all elements of the array.
fill方法只能用同一个值填充数组的各个位置,针对对象数组,就是复制同一个引用进行填充。

11.
import java.util.Arrays;

public class CopyingArrays {
  public static void main(String[] args) {
    int[] i = new int[7];
    int[] j = new int[10];
    Arrays.fill(i, 47);
    Arrays.fill(j, 99);
    System.out.println("i = " + Arrays.toString(i));
    System.out.println("j = " + Arrays.toString(j));
    System.arraycopy(i, 0, j, 0, i.length);
    System.out.println("j = " + Arrays.toString(j));
    int[] k = new int[5];
    Arrays.fill(k, 103);
    System.arraycopy(i, 0, k, 0, k.length);
    System.out.println("k = " + Arrays.toString(k));
    Arrays.fill(k, 103);
    System.arraycopy(k, 0, i, 0, k.length);
    System.out.println("i = " + Arrays.toString(i));
    // Objects:
    Integer[] u = new Integer[10];
    Integer[] v = new Integer[5];
    Arrays.fill(u, new Integer(47));
    Arrays.fill(v, new Integer(99));
    System.out.println("u = " + Arrays.toString(u));
    System.out.println("v = " + Arrays.toString(v));
    System.arraycopy(v, 0, u, u.length/2, v.length);
    System.out.println("u = " + Arrays.toString(u));
  }
}
System类的静态方法
它比用for循环复制数组要快很多。
arraycopy

public static void arraycopy(Object src,
                             int srcPos,
                             Object dest,
                             int destPos,
                             int length)

    Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination

array. A subsequence of array components are copied from the source array referenced by src to the destination array referenced by dest.

The number of components copied is equal to the length argument. The components at positions srcPos through srcPos+length-1 in the

source array are copied into positions destPos through destPos+length-1, respectively, of the destination array.
Parameters:
    src - the source array.
    srcPos - starting position in the source array.
    dest - the destination array.
    destPos - starting position in the destination data.
    length - the number of array elements to be copied.
上面的例子说明,基本类型与对象类型数组都可以复制。但是,如果复制对象数组,只是复制了对象的引用而不是对象本身的拷贝,这被称为浅复制。这个方法不会自动包装和拆包,两个数组必须具有相同的确切类型。

12.
Arrays类的静态方法:
equals

public static boolean equals(Object[] a,
                             Object[] a2)

    Returns true if the two specified arrays of Objects are equal to one another. The two arrays are considered equal if both arrays

contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. Two objects e1 and e2 are

considered equal if (e1==null ? e2==null : e1.equals(e2)). In other words, the two arrays are equal if they contain the same elements in

the same order. Also, two array references are considered equal if both are null.

    Parameters:
        a - one array to be tested for equality.
        a2 - the other array to be tested for equality.
    Returns:
        true if the two arrays are equal.
public class ComparingArrays {
  public static void main(String[] args) {
    int[] a1 = new int[10];
    int[] a2 = new int[10];
    Arrays.fill(a1, 47);
    Arrays.fill(a2, 47);
    System.out.println(Arrays.equals(a1, a2));
    a2[3] = 11;
    System.out.println(Arrays.equals(a1, a2));
    String[] s1 = new String[4];
    Arrays.fill(s1, "Hi");
    String[] s2 = { new String("Hi"), new String("Hi"),
      new String("Hi"), new String("Hi") };
    System.out.println(Arrays.equals(s1, s2));
  }
}
数组s1的所有元素都指向同一个元素,而s2包含不同的元素,但是比较的结果为true,数组的比较是基于内容的比较。


13.基本类型、包装类型、String都是值传递,即不管在函数里面怎么修改,原来的值不变;
   自定义类型都是引用传递,即在函数里面的修改,会影响到原来的值;

   数组,不管是基本类型、包装类型还是自定义类型,作参数数都是引用传递,会影响到原来的值;
分享到:
评论

相关推荐

    Java第5章 数组 含源代码

    Java第5章 数组 含源代码 Java第5章 数组 含源代码 Java第5章 数组 含源代码 Java第5章 数组 含源代码 Java第5章 数组 含源代码

    吉大数据结构课程 数据结构与算法课程 由浅入深 讲解清晰 03 第三章 数组和字符串(共101页).pptx

    数据结构课程,完整课程列表如下: 数据结构与算法课程01 第一章 绪论(共101页).ppt 数据结构与算法课程02 第二章 线性表、堆栈和队列(共147页).ppt ...数据结构与算法课程11 第十一章 随机数(共84页).ppt

    完整版精品java课件 Java基础入门教程 Java程序设计 第6章 数组和集合(共44页).ppt

    完整版精品java课件 Java基础入门教程 Java程序设计 第6章 数组和集合(共44页).ppt 完整版精品java课件 Java基础入门教程 Java程序设计 第7章 字符串处理(共38页).ppt 完整版精品java课件 Java基础入门教程 Java...

    推荐课程 完整版优质java教程 java精品教学课件 Java语言程序设计 第5章 数组(共58页).ppt

    推荐课程 完整版优质java教程 java精品教学课件 Java语言程序设计 第16章 网络编程(共33页).ppt 推荐课程 完整版优质java教程 java精品教学课件 Java语言程序设计 第1章 概述(共20页).ppt 推荐课程 完整版优质...

    数据结构试题分章节考研题及答案.rar

    历年数据结构考研题及答案,分章节管理第一章、绪论 试题 参考答案 第二章、线性表 试题 参考答案 第三 章、栈和队列 试题 参考答案 第四章、串 试题 参考答案 ...第十一章、文件 试题 参考答案

    全国计算机二级C语言等级考试视频教程-12-16章

    计算机二级C语言等级考试总16章,43小时,3.3g,视频教程,由于一次只能上传1g,所以分3个资源上传 12-16章 总目录: 第01章 程序设计 第02章 数据和表达式 第03章 输出和输入函数 ...第16章 六组文件函数的应用

    thinkingInJava7:第十六章:数组

    thinkingInJava7 第十六章:数组 yougengxin

    Java技术教程.基础篇

    第一章 java概述 第二章 数据类型 第三章 运算符和表达式 第四章 流程控制 第五章 java语言中的面向对象特性 第六章 数组 第七章 字符串处理 ...第十六章 网络通信 第十七章 JSP技术 以及它们的例子

    上海交大C++面向对象

    第一章 C++入门 第二章 基本数据类型与输入输出 第三章 表达式和语句 第四章 过程化语句 ...第十六章 继承 第十七章 多重继承 第十八章 运算符重载   第十九章 I/O流 第二十章 模板 第二一章 异常处理

    C语言全套资料 C语言程序设计 C语言算法 C语言课件

    C语言全套资料 C语言程序设计 C语言算法 C语言课件 C语言顺序程序设计 C语言数组 C语言循环控制...第六章 循环控制 第七章 数组 第八章 函数 第九章编译预处理命令 第十章 指针 第十一章 结构体与共用体 第十三章 文件

    Excel_VBA程序开发自学通正文

    第十六章 窗体控件运用案例 第十七章 表单控件与ActiveX控件 第十八章 VBA命令处理文件 第十九章 使用FileSystemObject和WScript 第二十章 磁盘与系统信息管理 第二十一章 认识Excel的内置命令栏对象 第二十二 创建...

    21天学会VB编程pp教程

    21学会vb编程 第一章概述 第二章语言基础 第三章程序控制结构 ...第十六章程序调试与除错 第十七章数据库系统与SQL语言 第十九章VB与数据库编程 第二十章数据报表生成 第二十一章人事管理系统开发实例

    全国计算机二级C语言等级考试视频教程-6-11章

    计算机二级C语言等级考试总16章,43小时,3.3g,视频教程,由于一次只能上传1g,所以分3个资源上传 6-11章 总目录: 第01章 程序设计 第02章 数据和表达式 第03章 输出和输入函数 ...第16章 六组文件函数的应用

    全国计算机二级C语言等级考试视频教程-1-5章

    计算机二级C语言等级考试,43小时,3.3g,视频教程,由于一次只能上传1g,所以分3个资源上传 目录: 第01章 程序设计 第02章 数据和表达式 第03章 输出和输入函数 第04章 运算符和表达式 ...第16章 六组文件函数的应用

    C++ PPT课件。。。。

    第一章 C++概述,第二章 数据类型、运算符与表达式,第三章 简单的输入输出,第四章 C++的流程控制语句,第五章 函数与编译预处理,第六章 数组 ,第七章 结构体、共同体和枚举类型 ,第八章 指针和引用,第九章 类...

    JavaScript权威指南

    第十六章 脚本化cookie 第十七章 文档对象模型 第十八章 级联样式表和动态HTML 第十九章 事件和事件处理 第二十章 兼容性 第二十一章 JavaScript的安全性 第二十二章 JavaScript中使用Java

    C语言第一章概述

    第一章:C语言程序设计概述 2...第六章:函数与编译预处理 4课时 第七章:数组 6课时 第八章:指针 8课时 第九章:结构体数据类型与链表 6课时 第十章:共用体与枚举类型 4课时 第十一章:文件

    JavaScript开发技术大全 - 光盘源代码.rar

    第02章 开始JavaScript 第03章 数据类型 第04章 直接量 ...第16章 其他对象操作 第17章 Cookie 第18章 文档对象模型 第19章 正则表达式 第20章 Ajax介绍 第21章 Ajax与服务器 第22章 Ajax与XML 第23章 Ajax与CSS

    C++primer 课后题答案

    C++primer 课后题答案 目录 第一章 快速入门 2 第二章 变量和基本类型 7 第三章 标准库类型 13 第四章 数组和指针 21 ...第十六章 部分选做习题 133 第十七章 用于大型程序的工具 138 第十八章 特殊工具与技术 138

    java 完整版PPT课件

    第01章 HelloWorld,第02章 变量,第03章 操作符与表达式,第04章 语句,第05章 数组,第06章 类,第07章 类的方法,第08章 当前对象,...静态方法与静态对象,第14章 常用工具类,第15章 链表,第16章 结语及补充示例

Global site tag (gtag.js) - Google Analytics