数组,你可以创建并组装它们,通过使用整型索引值访问它们的元素,并且它们的尺寸不能改变。

1、数组为什么特殊

数组与其他种类的容器之间的区别有三方面:效率、类型和保存基本类型的能力。在Java中数组是一种效率最高的存储和随机访问对象引用序列的方式。数组就是一个简单的线性序列,这使得元素访问非常快速。但是为这种速度所付出的代价是数组对象的大小被固定,并且在其生命周期中不可改变。

数组可以持有基本类型,而泛型之前的容器不能,但是由了泛型,容器就可以指定并检查它们所持有的对象的类型,并且有了自动包装机制。容器和数字持有对象的方式都是类型检查型的,并且唯一明显的差异就是数组使用[]来访问元素,而LIst使用的是add()和get()这样的方法。数组和ArrayList之间的相似性是有意义的,这两者之间的切换时很容易的。

泛型的出现使得容器也具备了类型检查的能力,而自动装箱机制使容器可以与数组几乎一模一样的用于基本类型,数组的硕果仅存的优点就是效率。

2、数组是第一级对象

无论使用哪种类型的数组,数组标识符其实只是一个引用,指向在堆中创建的一个真实对象,这个对象用以保存指向其他对象的引用。可以作为数组初始化语法的一部分隐式地创建此对象,或者用new表达式显式地创建。只读成员length是数组对象的一部分,表示此数组对象可以存储多少元素。”[]”语法是访问数组对象的唯一方式。对象数组和基本类型数组在使用上几乎是相同的,唯一的区别就是对象数组保存的是引用,基本类型数组直接保存基本类型的值。下面总结了初始化数组的各种方式:

在声明数组时可采用“聚集初始化”方法:

int[] integers = {0, 1, 2, 3, 4};

但是如果不在声明时初始化则必须采用“动态聚集初始化”方法:

int[] integers;

integers = new int[] {0, 1, 2, 3, 4};

3、多维数组

创建多维数组的方式:

对于基本类型的多维数组,可以通过使用花括号将每个向量分隔来,如二维数组:int a[][] = { { 1, 2, 3 }, { 4, 5, 6 }, };

使用new来分配数组,三维数组:int a[][][] = new int[2][2][4];

基本类型数组的值在不进行显式地初始化的情况下,会被自动地初始化。对象数组会被初始化为null。

Java 1.5新增的Arrays.deepToString()方法可以将多维数组转换为可读的String。数组中构造矩阵的每个向量都可以具有任意的长度,这被称为粗糙数组。

4、 数组与泛型

通常,数组与泛型不能很好地结合。你不能实例化具有参数化类型的数组,例如

Peel[] peels = new Peel[10]; //不合法

擦除会移除参数类型信息,而数组必须知道它们所持有的确切类型,以强制保证类型安全。但是可以创建非泛型的数组,然后将其转型为泛型数组,一旦拥有了泛型数组的引用,就会得到编译器检查。但是数组是协变的,因此List也是Object[],并且可以利用这一点把ArrayList赋值到数组中而不会有编译期或运行时错误:

List[] ls;

List[] la = new List[20];

ls = (List[])la;

ls[0] = new ArrayList();

//编译错误

//ls[1] = new ArrayList();

Object[] objects = ls;

objects[1] = new ArrayList();

如果确定将来不会向上转型,并且需求相对简单,那么可以创建泛型数组,它提供基本的编译器类型检查。但是泛型容器总是比泛型数组更好的选择。

5、创建测试数据

Java标准类库Arrays有一个作用十分有限的fill()方法,只能用同一个值填充各个位置,针对对象而言,就是复制同一个引用进行填充,还可以只填充数组的某个区域:

Arrays.fill(a9, “Hello”);

Arrays.fill(a9, 3, 5, “World”);

使用Arrays.fill()可以填充整个数组,或者只填充数组的某个区域。但是由于只能用单一的数值来调用Arrays.fill(),因此所产生的结果并非特别有用。

6、Arrays实用功能

在java.util类库中可以找到Arrays类,它有一套用于数组的static适用方法,其中有六个基本方法:equals()用于比较两个数组是否相等(deepEquals()用于多维数组);fill()在前面已经说过了;sort()用于对数组排序;binarySearch()用于在已经排序的数组中查找元素;toString()产生数组的String表示,hashCode()产生数组的散列码。所有这些方法对各种基本类型和Object类而重载过。次哇UArrays.List()接受任意的序列或数组作为其参数,并将其转变为List容器。

1)复制数组

Java标准类库提供static方法System.arraycopy(),用它复制数组比用for循环复制快很多。

格式为:System.arraycopy(Object src, int srcPosition, Object dest, int destPosition, int length);

基本类型数组与对象数组都可以复制。如果复制对象数组,只是复制了对象的引用——而不是对象本身的拷贝,这被称为浅复制。System.arraycopy()不会执行自动包装盒自动拆包,两个数组必须具有相同的确切类型。

2)数组的比较

Arrays类提供了静态equals()方法,用来比较整个数组。数组相等的条件是元素个数必须相等,并且对应位置的元素也相等,通过对每一个元素使用equals()方法来作比较。使用Arrays.deepEquals()可以比较多维数组。使用静态方法Arrays.sort()用语对数组进行排序。

3)数组元素的比较

Java有两种方式来提供比较功能:

第一种是实现java.lang.Comparable借口,使类具有天生的比较能力。此接口只有一个compareTo()方法,此方法接收另一个Object为参数,如果当前对象小于参数则返回负值,如果相等则返回零,如果当前对象大于参数则返回正值。如果对没有实现Comparable接口的类的数组进行排序,会抛出ClassCastException。因为sort()需要把参数的类型转换为Comparable。

另外一种,假设使用别人定义好的类并没有实现Comparable接口,或者类实现了Comparable接口但是需要另外一种比较方式。就需要创建一个实现了Comparator接口的单独的类。这是策略设计模式的一个应用实例。这个类有两个方法compare()和equals()方法。不一定要实现equals()方法,因为它间接的继承自Object的equals()方法。

4)数组排序

Collections类包含一个reverseOrder()静态方法可以产生一个Comparator,它可以翻转自然的排序顺序。

String的排序算法依据词典编排顺序排序,所以大写字母开头的词都放在前面,然后是小写字母。如果想忽略大小写可以使用String.CASE_INSENSITIVE_ORDER比较器。

5)在已排序的数组中查找

Java标准类库的排序算法对各种类型的正排序都进行了优化——针对基本类型设计的快速排序和针对对象设计的稳定归并排序。所以无需单行排序的性能。如果数组已经排好顺序就可以使用Arrays.binarySearch()执行快速查找。如果要对未排序的数组使用binarySearch()将产生不可预料的结果(可能指没找到元素的返回情况)。如果找到了目标,Arrays.binarySearch()产生的返回值大于或等于0.否则产生负返回值,表示若要保持数组的排序状态此目标元素应该插入的位置。这个负值的计算方式的:-(插入点)-1。插入点指第一个大于查找对象的元素在数组中的位置,如果数组中所有的元素都小于查找的对象,插入点就等于数组的长度。如果数组包含重复的元素,则无法保证找到的是这些副本中的哪一个。

如果需要对没有重复元素的数组排序可以使用TreeSet(保持排序顺序),或者LinkedHashSet(保持插入顺序)。这些类会自动处理所有细节。除非他们成为程序性能的瓶颈,否则不需要自己维护数组。

如果使用Comparator排序了某个对象数组,在使用binarySearch()时必须提供同样的Comparator。

java现有一个泛型类 提供数组排序功能,java编程思想读书笔记 第十六章 数组相关推荐

  1. Java编程思想读书笔记_第6章(访问权限)

    四种访问权限: public private 包访问权限 protected 如果没有明确指定package,则属于默认包 1 package access.dessert; 2 3 public c ...

  2. Java编程思想读书笔记(02)

    第十三章字符串 字符串是不可变的:是final类固不能继承它:也不能通过指向它的引用来修改它的内容. StringBuilder是Java SE5引用的,在这之前用的是StringBuffer.后者是 ...

  3. Think in Java第四版 读书笔记10 第16章 数组

    Think in Java第四版 读书笔记10 第16章 数组 数组和容器很像 但他们有一些差别 16.1 数组为什么特殊 数组与容器的区别主要在效率和存储类型 效率:数组是简单的线性序列 使得数组的 ...

  4. JAVA编程思想读书笔记(三)--RTTI

    接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...

  5. JAVA编程思想——读书笔记 对象的容纳

    文章目录 对象的容纳 1.数组(array) 数组和第一类对象 基本数据类型集合 数组的返回 2.集合(collection) 集合的缺点:类型未知 它不适用于一下场合: 1.错误有时显露不出来 生成 ...

  6. Java编程思想读书笔记——第七章:复用类

    第七章 复用类 使用类而不破坏现有程序代码,有两种达到这一目的的方法: 在新的类中产生现有类的对象,也就是说new一个对象,这种方法称为组合 按照现有类的类型来创建新类,不改变现有类的形式,在其基础上 ...

  7. Java编程思想读书笔记一:并发

    1. Thread.yield( )方法 当调用yield()时,即在建议具有相同优先级的其他线程可以运行了,但是注意的是,仅仅是建议,没有任何机制保证你这个建议会被采纳 .一般情况下,对于任何重要的 ...

  8. java编程思想读书笔记

    多态 任何域的访问操作都将有编译器解析,如果某个方法是静态的,它的行为就不具有多态性 java默认对象的销毁顺序与初始化顺序相反 编写构造器时有一条有效的准则:"尽可能用简单的方法使对象进入 ...

  9. Java编程思想读书笔记——字符串

    第十三章 字符串 13.1 不可变String String对象是不可变的(不能够原地修改),具备只读特性.String类中每一个修改String值的方法,实际上是创建了一个新的String对象. 当 ...

最新文章

  1. panads 访问 csv 数据集
  2. 测试用例的常用设计方法
  3. JavaScript知识点总结(二)
  4. HTML中的Content-Type的类型
  5. 一张图说明我们为什么要关注 HTML5
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的医药信息管理系统
  7. JAVA—字符串怎么转换成整数
  8. node读写xlsx文件
  9. jQuery插件开发标准写法
  10. 《Linux管理与应用》课程考核方案
  11. 如何免费注册一个域名?
  12. 用 HTML 做一个表单模板
  13. 算法设计与分析之分治法
  14. pushpush(双向队列/列表)
  15. tomcat8.5服务开启zabbix远程监控配置修改
  16. 使用cpolar建立固定的SSH隧道
  17. 操作系统实验:存储管理(C++)
  18. 大疆无人机安卓Mobile Sdk开发(五)解决M300Rtk H20相机无法获取图片视频的问题
  19. JavaIO知识简述
  20. 《Java 2 实用教程》读书笔记(四)4.4

热门文章

  1. Python3:ImportError: No module named 'compiler.ast'
  2. CVD和ALD薄膜沉积技术应用领域
  3. Apollo 自动驾驶开发套件(D-KIT)
  4. NSight Compute 用户手册(中)
  5. TOF摄像机可以替代Flash激光雷达吗?
  6. 2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数
  7. 关于oracle的基础增删改查操作总结
  8. BZOJ4152 AMPPZ2014 The Captain(最短路)
  9. Showstopper [POJ3484] [二分] [思维]
  10. C++ 笔记(15)— 引用(声明引用、引用作为参数、引用作为函数返回值、const 用于引用)