按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
char'' buf = new char'length';
int rnd;
for(int i = 0; i 《 length; i++) {
rnd = Math。abs(r。nextInt()) % src。length;
buf'i' = src'rnd';
}
return new String(buf);
}
// Create a random array of Strings:
public static
255
…………………………………………………………Page 257……………………………………………………………
String'' randStrings(int length; int size) {
String'' s = new String'size';
for(int i = 0; i 《 size; i++)
s'i' = randString(length);
return s;
}
public static void print(byte'' b) {
for(int i = 0; i 《 b。length; i++)
System。out。print(b'i' + 〃 〃);
System。out。println();
}
public static void print(String'' s) {
for(int i = 0; i 《 s。length; i++)
System。out。print(s'i' + 〃 〃);
System。out。println();
}
public static void main(String'' args) {
byte'' b = new byte'15';
r。nextBytes(b); // Fill with random bytes
print(b);
Arrays。sort(b);
print(b);
int loc = Arrays。binarySearch(b; b'10');
System。out。println(〃Location of 〃 + b'10' +
〃 = 〃 + loc);
// Test String sort & search:
String'' s = randStrings(4; 10);
print(s);
Arrays。sort(s);
print(s);
loc = Arrays。binarySearch(s; s'4');
System。out。println(〃Location of 〃 + s'4' +
〃 = 〃 + loc);
}
} ///:~
类的第一部分包含了用于产生随机字串对象的实用工具,可供选择的随机字母保存在一个字符数组中。
randString()返回一个任意长度的字串;而 readStrings()创建随机字串的一个数组,同时给定每个字串的
长度以及希望的数组大小。两个print()方法简化了对示范数组的显示。在 main()中,Random。nextBytes()
用随机选择的字节填充数组自变量(没有对应的Random 方法用于创建其他基本数据类型的数组)。获得一个
数组后,便可发现为了执行sort()或者 binarySearch(),只需发出一次方法调用即可。与binarySearch()
有关的还有一个重要的警告:若在执行一次binarySearch()之前不调用 sort(),便会发生不可预测的行为,
其中甚至包括无限循环。
对String 的排序以及搜索是相似的,但在运行程序的时候,我们会注意到一个有趣的现象:排序遵守的是字
典顺序,亦即大写字母在字符集中位于小写字母的前面。因此,所有大写字母都位于列表的最前面,后面再
跟上小写字母——Z 居然位于a 的前面。似乎连电话簿也是这样排序的。
2。 可比较与比较器
但假若我们不满足这一排序方式,又该如何处理呢?例如本书后面的索引,如果必须对以A 或a 开头的词条
分别到两处地方查看,那么肯定会使读者颇不耐烦。
若想对一个 Object 数组进行排序,那么必须解决一个问题。根据什么来判定两个 Object 的顺序呢?不幸的
是,最初的 Java 设计者并不认为这是一个重要的问题,否则就已经在根类 Object 里定义它了。这样造成的
256
…………………………………………………………Page 258……………………………………………………………
一个后果便是:必须从外部进行Object 的排序,而且新的集合库提供了实现这一操作的标准方式(最理想的
是在Object 里定义它)。
针对Object 数组(以及 String,它当然属于Object 的一种),可使用一个 sort(),并令其接纳另一个参
数:实现了 parator 接口(即“比较器”接口,新集合库的一部分)的一个对象,并用它的单个
pare()方法进行比较。这个方法将两个准备比较的对象作为自己的参数使用——若第一个参数小于第二
个,返回一个负整数;若相等,返回零;若第一个参数大于第二个,则返回正整数。基于这一规则,上述例
子的String 部分便可重新写过,令其进行真正按字母顺序的排序:
//: Alphap。java
// Using parator to perform an alphabetic sort
package c08。newcollections;
import java。util。*;
public class Alphap implements parator {
public int pare(Object o1; Object o2) {
// Assume it's used only for Strings。。。
String s1 = ((String)o1)。toLowerCase();
String s2 = ((String)o2)。toLowerCase();
return s1。pareTo(s2);
}
public static void main(String'' args) {
String'' s = Array1。randStrings(4; 10);
Array1。print(s);
Alphap ac = new Alphap();
Arrays。sort(s; ac);
Array1。print(s);
// Must use the parator to search; also:
int loc = Arrays。binarySearch(s; s'3'; ac);
System。out。println(〃Location of 〃 + s'3' +
〃 = 〃 + loc);
}
} ///:~
通过造型为 String,pare()方法会进行“暗示”性的测试,保证自己操作的只能是String 对象——运行
期系统会捕获任何差错。将两个字串都强迫换成小写形式后,String。pareTo()方法会产生预期的结果。
若用自己的 parator 来进行一次 sort(),那么在使用binarySearch()时必须使用那个相同的
parator。
Arrays 类提供了另一个 sort()方法,它会采用单个自变量:一个 Object 数组,但没有parator。这个
sort()方法也必须用同样的方式来比较两个 Object。通过实现parable 接口,它采用了赋予一个类的
“自然比较方法”。这个接口含有单独一个方法——pareTo(),能分别根据它小于、等于或者大于自变量
而返回负数、零或者正数,从而实现对象的比较。下面这个例子简单地阐示了这一点:
//: pClass。java
// A class that implements parable
package c08。newcollections;
import java。util。*;
public class pClass implements parable {
private int i;
public pClass(int ii) { i = ii; }
public int pareTo(Object o) {
// Implicitly tests for correct type:
257
…………………………………………………………Page 259……………………………………………………………
int argi = ((pClass)o)。i;
if(i == argi) return 0;
if(i 《 argi) return …1;
return 1;
}
public static void print(Object'' a) {
for(int i = 0; i 《 a。length; i++)
System。out。print(a'i' + 〃 〃);
System。out。println();
}
public String toString() { return i + 〃〃; }
public static void main(String'' args) {
pClass'' a = new pClass'20';
for(int i = 0; i 《 a。length; i++)
a'i' = new pClass(
(int)(Math。random() *100));
print(a);
Arrays。sort(a);
print(a);
int loc = Ar