JAVA编程思想学习 — JAVA中通用排序的具体做法

编写通用的排序代码时,面临的一个问题是 必须根据对象的实际类型来执行比较运算,从而实现正确的排 序。当然,一个办法是为每种不同的类型都写一个不同的排序方法。然而,应认识到假若这样做,以后增加 新类型时便不易实现代码的重复利用。
     程序设计一个主要的目标就是“ 将发生变化的东西同保持不变的东西分隔开”。在这里, 保持不变的代码是 通用的排序算法,而每次使用时都要变化的是对象的实际比较方法。因此,我们不可将比较代码“硬编码” 到多个不同的排序例程内,而是采用“回调”技术。利用回调,经常发生变化的那部分代码会封装到它自己 的类内,而总是保持相同的代码则“回调”发生变化的代码这样一来,不同的对象就可以表达不同的比较 方式,同时向它们传递相同的排序代码。

     下面这个“接口”( Interface)展示了如何比较两个对象,它将那些“要发生变化的东西”封装在内(摘自JAVA编程思想 第四版 第八章): 

//: Compare.java
// Interface for sorting callback:
package c08;
interface Compare {
  boolean lessThan(Object lhs, Object rhs);
  boolean lessThanOrEqual(Object lhs, Object rhs);
} ///:~

 对这两种方法来说, lhs 代表本次比较中的“左手”对象,而 rhs 代表“右手”对象。(如果对这一部分不理解的同学,请自行学习 数据结构--快速排序)

下面是快速排序的过程 
//: SortVector.java
// A generic sorting vector
package c08;
import java.util.*;
public class SortVector extends Vector {
  private Compare compare; // To hold the callback
  public SortVector(Compare comp) {
    compare = comp;
  }
  public void sort() {
    quickSort(0, size() - 1);
  }
  private void quickSort(int left, int right) {
    if(right > left) {
      Object o1 = elementAt(right);
      int i = left - 1;
      int j = right;
      while(true) {
        while(compare.lessThan(
            elementAt(++i), o1))
          ;
        while(j > 0)
          if(compare.lessThanOrEqual(
              elementAt(--j), o1))
            break; // out of while
        if(i >= j) break;
        swap(i, j);
      }
      swap(i , right);
      quickSort(left, i-1);
      quickSort(i+1, right);
    }
  }
  private void swap(int loc1, int loc2) {
    Object tmp = elementAt(loc1);
    setElementAt(elementAt(loc2), loc1);
    setElementAt(tmp, loc2);
  }
} ///:~

现在,大家可以明白“ 回调”一词的来历,这是由于 quickSort()方法“往回调用”了 Compare 中的方法。 从中亦可理解这种技术如何生成通用的、可重复利用(再生)的代码。
     为使用 SortVector,必须创建一个类,令其为我们准备排序的对象实现 Compare。此时内部类并不显得特别 重要,但对于代码的组织却是有益的。下面是针对 String 对象的一个例子:
//: StringSortTest.java
// Testing the generic sorting Vector
package c08;
import java.util.*;
public class StringSortTest {
  static class StringCompare implements Compare {
    public boolean lessThan(Object l, Object r) {
      return ((String)l).toLowerCase().compareTo(
          ((String)r).toLowerCase()) < 0;
    }
    public boolean
    lessThanOrEqual(Object l, Object r) {
      return ((String)l).toLowerCase().compareTo(
          ((String)r).toLowerCase()) <= 0;
    }
  }
  public static void main(String[] args) {
    SortVector sv =
        new SortVector(new StringCompare());
    sv.addElement("d");
    sv.addElement("A");
    sv.addElement("C");
    sv.addElement("c");
    sv.addElement("b");
    sv.addElement("B");
    sv.addElement("D");
    sv.addElement("a");
    sv.sort();
    Enumeration e = sv.elements();
    while(e.hasMoreElements())
    System.out.println(e.nextElement());
  }
} ///:~

内部类是“静态”( Static)的,因为它毋需连接一个外部类即可工作。 大家可以看到,一旦设置好框架,就可以非常方便地重复使用象这样的一个设计—— 只需简单地写一个类, 将“需要发生变化”的东西封装进去,然后将一个对象传给SortVector 即可。

    Java中实现排序的流程是,将不变的代码部分封装起来,将需要经常改变的部分(两个参数的比较等)封装到自己的类中,这也就是为什么需要用到排序功能是一定要实现 Comparable 的原因.

最近在看JAVA编程思想(第四版)这本书,将书中的一些知识点容易遇到或者混淆的概念记录下来,只是作为备忘,希望也能帮到需要的人,特此申明.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶孤心丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值