Java编程思想 数组总结

数组为什么特殊
数组与其他种类的容器之间的区别有三方面 效率 类型和保存基本类型的能力
数组可以持有基本类型 而泛型之前的容器则不能 但是有了泛型 容器就可以指定并检查它们所持有对象的类型 并且有了自动包装机制 容器看起来还能够持有基本类型 下面是将数组与泛型容器进行比较的示例
在这里插入图片描述
在这里插入图片描述

数组是第一级对象
下例总结了初始化数组的各种方式 以及如何对指向数组的引用赋值 使之指向另一个数组对象 此例也说明 对象数组和基本类型数组在使用上几乎是相同的 唯一的区别就是对象数组保存的是引用 基本类型数组直接保存基本类型的值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

返回一个数组
下例演示如何返回String型数组
在这里插入图片描述
在这里插入图片描述

多维数组
创建多维数组很方便 对于基本类型的多维数组 可以通过使用花括号将每个向量分隔开
在这里插入图片描述

下面的示例使用了Java SE5的Arrays.deepToString()方法 它可以将多维数组转换为多个String 正如从输出中所看到的那样 还可以使用new来分配数组 下面的三维数组就是在new表达式中分配的
在这里插入图片描述

数组中构成矩阵的每个向量都可以具有任意的长度(这被称为粗糙数组)
在这里插入图片描述

可以用类似的方式处理非基本类型的对象数组 下面 你可以看到如何用花括号把多个new表达式组织到一起
在这里插入图片描述
在这里插入图片描述

自动包装机制对数组初始化器也起作用
在这里插入图片描述

下面的示例展示了可以如何逐个地 部分地构建一个非基本类型的对象数组
在这里插入图片描述

Arrays.deepToString()方法对基本类型数组和对象数组都起作用
在这里插入图片描述
在这里插入图片描述

数组与泛型
通常 数组与泛型不能很好地结合 你不能实例化具有参数化类型的数组
在这里插入图片描述
擦除会移除参数类型信息 而数组必须知道它们所持有的确切类型 以强制保证类型安全
但是 你可以参数化数组本身的类型
在这里插入图片描述

正如上例所证明的那样 不能创建泛型数组这一说法并不十分准确 诚然 编译器确实不让你实例化泛型数组 但是 它允许你创建对这种数组的引用 例如
在这里插入图片描述
这条语句可以顺利地通过编译器而不报任何错误 而且 尽管你不能创建实际的持有泛型的数组对象 但是你可以创建非泛型的数组 然后将其转型
在这里插入图片描述

一般而言 你会发现泛型在类或方法的边界处很有效 而在类或方法的内部 擦除通常会使泛型变得不适用 例如 你不能创建泛型数组
在这里插入图片描述

创建测试数据

Arrays.fill()
Java标准类库Arrays有一个作用十分有限的fill()方法 只能用同一个值填充各个位置 而针对对象而言 就是复制同一个引用进行填充 下面是一个示例
在这里插入图片描述
在这里插入图片描述

数据生成器
首先给出的是可以用于所有基本类型的包装器类型 以及String类型的最基本的计数生成器集合 这些生成器类都嵌套在CountingGenerator类中 从而使得它们能够使用与所要生成的对象类型相同的名字 例如 创建Integer对象的生成器可以通过表达式new CountingGenerator.Integer()来创建
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面是一个测试工具 针对嵌套的Generator这一惯用法 因为使用了反射所以这个工具可以遵循下面的形式来测试Generator的任何集合
在这里插入图片描述
在这里插入图片描述

下面是一组使用随机数生成器的Generator 因为Random构造器使用常量进行初始化 所以 每次用这些Generator中的一个来运行程序时 所产生的输出都是可重复的
在这里插入图片描述
在这里插入图片描述

为了不生成过大的数字 RandomGenerator.Integer默认使用的模数为10000 但是重载的构造器允许你选择更小的值 同样的方式也应用到了RandomGenerator.Long上 对于Float和Double生成器 小数点之后的数字被截掉了
我们复用GeneratorTest来测试RandomGenerator
在这里插入图片描述
在这里插入图片描述

从Generator中创建数组
为了接收Generator并产生数组 我们需要两个转换工具 第一个工具使用任意的Generator来产生Object子类型的数组 为了处理基本类型 第二个工具接收任意基本类型的包装器类型数组 并产生相应的基本类型数组
第一个工具有两种选项 并由重载的静态方法array()来表示 该方法的第一个版本接收一个已有的数组 并使用某个Generator来填充它 而第二个版本接收一个Class对象 一个Generator和所需的元素数量 然后创建一个新数组 并使用所接收的Generator来填充它 注意 这个工具只能产生Object子类型的数组 而不能产生基本类型数组
在这里插入图片描述
CollectionData类将创建一个Collection对象 该对象中所填充的元素是由生成器gen产生的 而元素的数量则由构造器的第二个参数确定 所有的Collection子类型都拥有toArray()方法 该方法将使用Collection中的元素来填充参数数组
第二个方法使用反射来动态创建具有恰当类型和数量的新数组 然后使用与第一个方法相同的技术来填充该数组
我们可以使用在前面定义的CountingGenerator类中的某个生成器来测试Generated
在这里插入图片描述
在这里插入图片描述

泛型不能用于基本类型 而我们确实想用生成器来填充基本类型数组 为了解决这个问题 我们创建了一个转换器 它可以接收任意的包装器对象数组 并将其转换为相应的基本类型数组 如果没有这个工具 我们就必须为所有的基本类型创建特殊的生成器
在这里插入图片描述
在这里插入图片描述

下面的示例展示了如何将ConvertTo应用于两个版本的Generated.array()上
在这里插入图片描述

下面的程序将使用RandomGenerator中的类来测试这些数组生成工具
在这里插入图片描述
在这里插入图片描述

Arrays实用功能
Java标准类库提供有static方法System.arraycopy() 用它复制数组比用for循环复制要快很多 System.arraycopy()针对所有类型做了重载 下面的例子就是用来处理int数组的
在这里插入图片描述
在这里插入图片描述

这个例子说明基本类型数组与对象数组都可以复制 然而 如果复制对象数组 那么只是复制了对象的引用 而不是对象本身的拷贝 这被称作浅复制(shallow copy)
System.arraycopy()不会执行自动包装和自动拆包 两个数组必须具有相同的确切类型

数组的比较
Arrays类提供了重载后的equals()方法 用来比较整个数组 同样 此方法针对所有基本类型与Object都做了重载 数组相等的条件是元素个数必须相等 并且对应位置的元素也相等 这可以通过对每一个元素使用equals()作比较来判断(对于基本类型 需要使用基本类型的包装器类的equals()方法 例如 对于int类型使用Integer.equals()作比较)见下例
在这里插入图片描述
在这里插入图片描述

数组元素的比较
Java有两个方式来提供比较功能 第一种是实现java.lang.Comparable接口 使你的类具有 天生 的比较能力 此接口很简单 只有compareTo()一个方法 此方法接收另一个Object为参数 如果当前对象小于参数则返回负值 如果相等则返回零 如果当前对象大于参数则返回正值
下面的类实现了Comparable接口 并且使用Java标准类库的方法Arrays.sort()演示了比较的效果
在这里插入图片描述
在这里插入图片描述

Collection类包含一个reverseOrder()方法 该方法可以产生一个Comparator 它可以反转自然的排序顺序 这很容易应用于CompType
在这里插入图片描述
在这里插入图片描述
也可以编写自己的Comparator 在这里的CompType对象是基于j值而不是基于i值的
在这里插入图片描述

数组排序
使用内置的排序方法 就可以对任意的基本类型数组排序 也可以对任意的对象数组进行排序 只要该对象实现了Comparator接口或具有相关联的Comparator 下面的例子生成随机的String对象 并对其排序
在这里插入图片描述

在已排序的数组中查找
如果数组已经排好序了 就可以使用Arrays.binarySearch()执行快速查找 如果要对未排序的数组使用binarySearch() 那么将产生不可预料的结果 下面的例子使用RandIntGenerator.Integer填充数组 然后再使用同样的生成器生成要查找的值
在这里插入图片描述
在这里插入图片描述

如果使用Comparator排序了某个对象数组(基本类型数组无法使用Comparator进行排序) 在使用binarySearch()时必须提供同样的Comparator(使用binarySearch()方法的重载版本) 例如 可以修改StringSorting.java程序以进行某种查找
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值