22.JAVA编程思想——排序和搜索

Java 1.2 添加了自己的一套实用工具,可用来对数组或列表进行排列和搜索。这些工具都属于两个新类的“静态”方法。这两个类分别是用于排序和搜索数组的Arrays,以及用于排序和搜索列表的Collections。

1     数组

Arrays 类为所有基本数据类型的数组提供了一个过载的sort()和binarySearch(),它们亦可用于String 和Object。下面这个例子显示出如何排序和搜索一个字节数组(其他所有基本数据类型都是类似的)以及一个String 数组:

1.1     代码

import java.util.*;

public class Array1 {

static Random r= newRandom();

static String ssource = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz";

static char[]src= ssource.toCharArray();

// Create arandom String

public staticString randString(int length){

char[] buf = newchar[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 arandom array of Strings:

public staticString[] randStrings(int length,intsize){

String[] s = new String[size];

for (int i = 0; i < size; i++)

s[i] = randString(length);

return s;

}

public staticvoidprint(byte[]b) {

for (int i = 0; i < b.length; i++)

System.out.print(b[i] + " ");

System.out.println();

}

public staticvoidprint(String[] s){

for (int i = 0; i < s.length; i++)

System.out.print(s[i] + " ");

System.out.println();

}

public staticvoidmain(String[] args){

byte[] b = newbyte[15];

r.nextBytes(b); // Fill withrandom 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);

}

} /// :~

1.2     执行结果

98-34 -68 -95 31 54 120 46 50 15 1 49 25 80 120

-95-68 -34 1 15 25 31 46 49 50 54 80 98 120 120

Locationof 54 = 10

vmdoGxLR IunY EXKM yzdY Veng HKbB zZRw RnVS SmoD

EXKMGxLR HKbB IunY RnVS SmoD Veng vmdo yzdY zZRw

Locationof RnVS = 4

1.3     代码说明

类的第一部分包含了用于产生随机字串对象的实用工具,可供选择的随机字母保存在一个字符数组中。

randString()返回一个任意长度的字串;而readStrings()创建随机字串的一个数组,同时给定每个字串的长度以及希望的数组大小。两个print()方法简化了对示范数组的显示。在main()中,Random.nextBytes()用随机选择的字节填充数组自变量(没有对应的Random方法用于创建其他基本数据类型的数组)。获得一个数组后,便可发现为了执行sort()或者binarySearch(),只需发出一次方法调用即可。与binarySearch()有关的还有一个重要的警告:若在执行一次binarySearch()之前不调用sort(),便会发生不可预测的行为,其中甚至包括无限循环。

对String 的排序以及搜索是相似的,但在运行程序的时候,我们会注意到一个有趣的现象:排序遵守的是字典顺序,亦即大写字母在字符集中位于小写字母的前面。因此,所有大写字母都位于列表的最前面,后面再跟上小写字母——Z 居然位于a 的前面。似乎连电话簿也是这样排序的。

2     可比较与比较器

但假若我们不满足这一排序方式,又该如何处理呢?如果必须对以A 或a 开头的词条分别到两处地方查看,那么肯定会使读者颇不耐烦。

若想对一个Object 数组进行排序,那么必须解决一个问题。根据什么来判定两个Object 的顺序呢?不幸的是,最初的Java 设计者并不认为这是一个重要的问题,否则就已经在根类Object 里定义它了。这样造成的一个后果便是:必须从外部进行Object 的排序,而且新的集合库提供了实现这一操作的标准方式(最理想的是在Object 里定义它)。

针对Object 数组(以及String,它当然属于Object 的一种),可使用一个sort(),并令其接纳另一个参数:实现了Comparator 接口(即“比较器”接口,新集合库的一部分)的一个对象,并用它的单个compare()方法进行比较。这个方法将两个准备比较的对象作为自己的参数使用——若第一个参数小于第二个,返回一个负整数;若相等,返回零;若第一个参数大于第二个,则返回正整数。基于这一规则,上述例子的String 部分便可重新写过,令其进行真正按字母顺序的排序:

2.1     代码如下:

import java.util.*;

public class AlphaComp implements Comparator{

public intcompare(Object o1,Object o2){

// Assume it's used only for Strings...

String s1 = ((String) o1).toLowerCase();

String s2 = ((String) o2).toLowerCase();

return s1.compareTo(s2);

}

public staticvoidmain(String[] args){

String[] s = Array1.randStrings(4, 10);

Array1.print(s);

AlphaComp ac = new AlphaComp();

Arrays.sort(s, ac);

Array1.print(s);

// Must use the Comparator to search, also:

int loc = Arrays.binarySearch(s, s[3], ac);

System.out.println("Location of " + s[3] + " = " + loc);

}

} /// :~

2.2     执行如下:

CIurMMxl UKSJ HVkY YZaF MHTg kuhV FRAk Vhgj AyBq

AyBqCIur FRAk HVkY kuhV MHTg MMxl UKSJ Vhgj YZaF

Locationof HVkY = 3

2.3     代码说明

通过造型为String,compare()方法会进行“暗示”性的测试,保证自己操作的只能是String 对象——运行期系统会捕获任何差错。将两个字串都强迫换成小写形式后,String.compareTo()方法会产生预期的结果。若用自己的Comparator 来进行一次sort(),那么在使用binarySearch()时必须使用那个相同的Comparator。

Arrays 类提供了另一个sort()方法,它会采用单个自变量:一个Object 数组,但没有Comparator。这个sort()方法也必须用同样的方式来比较两个Object。通过实现Comparable 接口,它采用了赋予一个类的“自然比较方法”。这个接口含有单独一个方法——compareTo(),能分别根据它小于、等于或者大于自变量而返回负数、零或者正数,从而实现对象的比较。

2.4     代码2

import java.util.*;

public class CompClass implements Comparable{

private inti;

public CompClass(intii){

i = ii;

}

public int compareTo(Object o) {

// Implicitly tests for correct type:

int argi = ((CompClass)o).i;

if(i == argi)return0;

if(i < argi)return-1;

return 1;

}

public staticvoidprint(Object[] a){

for (int i = 0; i < a.length; i++)

System.out.print(a[i] + " ");

System.out.println();

}

public String toString() {

return i + "";

}

public staticvoidmain(String[] args){

CompClass[] a = new CompClass[20];

for (int i = 0; i < a.length; i++)

a[i] = newCompClass((int)(Math.random() * 100));

print(a);

Arrays.sort(a);

print(a);

int loc = Arrays.binarySearch(a, a[3]);

System.out.println("Location of " + a[3] + " = " + loc);

}

} /// :~

2.5     执行如下

88 34 78 64 29 70 1 25 10 39 95 9 36 74 97 82 69 20 66

18 8 9 10 20 25 29 34 36 39 64 66 69 70 74 78 82 95 97

Locationof 9 = 3

3     列表

可用与数组相同的形式排序和搜索一个列表(List)。用于排序和搜索列表的静态方法包含在类

Collections 中,但它们拥有与Arrays 中差不多的签名:sort(List)用于对一个实现了Comparable 的对象列表进行排序;binarySearch(List,Object)用于查找列表中的某个对象;sort(List,Comparator)利用一个“比较器”对一个列表进行排序;而binarySearch(List,Object,Comparator)则用于查找那个列表中的一个对象。下面这个例子利用了预先定义好的CompClass 和AlphaComp 来示范Collections 中的各种排序工具:

3.1     代码如下

import java.util.*;

public class ListSort {

public staticvoidmain(String[] args){

final int SZ = 20;

// Using "natural comparison method":

List a = new ArrayList();

for (int i = 0; i < SZ; i++)

a.add(new CompClass((int) (Math.random() *100)));

Collection1.print(a);

Collections.sort(a);

Collection1.print(a);

Object find = a.get(SZ/ 2);

int loc = Collections.binarySearch(a, find);

System.out.println("Location of " + find + " = " + loc);

// Using a Comparator:

List b = new ArrayList();

for (int i = 0; i < SZ; i++)

b.add(Array1.randString(4));

Collection1.print(b);

AlphaComp ac = new AlphaComp();

Collections.sort(b, ac);

Collection1.print(b);

find = b.get(SZ/ 2);

// Must use the Comparator to search, also:

loc = Collections.binarySearch(b, find, ac);

System.out.println("Location of " + find + " = " + loc);

}

} /// :~

3.2     执行如下

3861 43 10 90 92 32 14 22 81 38 13 95 25 62 52 76 76 35 65

1013 14 22 25 32 35 38 38 43 52 61 62 65 76 76 81 90 92 95

Locationof 52 = 10

lSgYMpSR skmc CoEw IPzS YQQU CTiU TRYc FaHh uAsm oehY zpTa dktG SiMp KpZh lBro oJFPXnbe eHlZ UqsH

CoEwCTiU dktG eHlZ FaHh IPzS KpZh lBro lSgY MpSR oehY oJFP SiMp skmc TRYc uAsm UqsHXnbe YQQU zpTa

Locationof oehY = 10

这些方法的用法与在Arrays 中的用法是完全一致的,只是用一个列表代替了数组。

TreeMap 也必须根据Comparable或者Comparator 对自己的对象进行排序。

22.JAVA编程思想——排序和搜索相关推荐

  1. 【java】《java编程思想》 读书笔记

    之前主要用的C++的比较多,之前花了快2个月的实际认真系统全面的学习了以下java的基础语法,<java编程思想>这本书翻译水平确实不是很好,很多话读着会比较拗口.推荐读之前,先去网上搜索 ...

  2. java编程思想--概述

    之前主要用的C++的比较多,之前花了快2个月的实际认真系统全面的学习了以下java的基础语法,<java编程思想>这本书翻译水平确实不是很好,很多话读着会比较拗口.推荐读之前,先去网上搜索 ...

  3. Java编程思想第四版学习总结

    Java编程思想第四版学习总结 文章目录 Java编程思想第四版学习总结 第 1 章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重 ...

  4. 33.JAVA编程思想——JAVA IO File类

    33.JAVA编程思想--JAVA IO File类 RandomAccessFile用于包括了已知长度记录的文件.以便我们能用 seek()从一条记录移至还有一条:然后读取或改动那些记录. 各记录的 ...

  5. Java编程思想学习笔记-第11章

    <?xml version="1.0" encoding="utf-8"?> Java编程思想学习笔记-第11章 Java编程思想学习笔记-第11章 ...

  6. Java编程思想日志

    Thinking In Java的作者是大牛!做事要站在巨人的肩膀上有助于提高效率和开阔眼界!建议学习java的小伙伴儿有时间可以抽空了解一下,以下内容为读书笔记,比较杂乱,仅供参考,推荐阅读原著: ...

  7. java编程思想读书心得

    Thinking In Java 写这篇文章的主要目的是记录java编程思想这本书的重点内容,一来可以分享给大家一起讨论学习,二来总结知识提升自己. 第一章:对象导论 java面向对象的理解 将组成问 ...

  8. 35.JAVA编程思想——JAVA IO StreamTokenizer

    35.JAVA编程思想--JAVA IO StreamTokenizer 尽管StreamTokenizer并不是从 InputStream或 OutputStream衍生的,但它只随同InputSt ...

  9. 《Java编程思想》读书笔记(二)

    三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第一章到第十章的内容,这一次记录的是第 ...

最新文章

  1. 利用CStopWatch计算并显示小车运行速度
  2. 表单序列化提交中文乱码解决方案
  3. Linux 中 ss 命令的使用实例介绍
  4. office2016打开PPT出现解决VBE6EXT.OLB不能被加载问题的解决办法
  5. Android之解决ViewPager2+PhotoView滑动图片花屏问题
  6. 将Java Flight Recorder与OpenJDK 11结合使用
  7. linux下安装pm2
  8. jsp java循环读取json_JAVA JSON遍历问题,求解(内附代码)
  9. leetcode 172 python
  10. Linux_JDK安装
  11. 免费资源下载:暗色色系的超棒搜索框和下拉菜单UI欣赏
  12. jquery uploadify 相关文档 按钮样式显示不全 Google浏览器显示问题
  13. 二、信号分解 —> 变分模态分解(VMD)学习笔记
  14. 史上最详细Sqlyog详细安装教程及使用
  15. GitKraken -- 超好用的 Git 可视化工具
  16. OSPF配置命令及外部选路
  17. 小米手机隐私相册在哪?将你的照片锁进“保险柜”
  18. android tablayout放图片,Android TabLayout的Indicator如何设置为图片
  19. 优质的服务器机房有哪些表现
  20. [置顶] 增强型的FLEA_Db_TableDataGateway,提供按字段名称操作的功能

热门文章

  1. 学成在线 职业规划 页面
  2. 自制显示器支架_如何选择合适的显示器支架
  3. Android开发:长连接通信设计与实现
  4. Unity编辑器下添加圆锥模型
  5. puppeteer(一)环境搭建——新Web自动化工具(同selenium)
  6. 网络变压器国产替代:国家安可计划与PULSE网络变压器产品国产化替代成果
  7. Q2付费用户“涨停”,奈飞靠游戏+电商带动“起飞”?
  8. 电脑键盘上的灰尘怎么清除?5个小妙招轻松对灰尘say拜!
  9. java将数字格式化为万或者千亿或者 以亿为单位
  10. H5页面内嵌到微信小程序和APP,做分享操作