接口與回調
回調(callback)是一種常見的程序設計模式。在這種模式中,可以指出某個特定事件發生時應該採取的動作。如,可以指出在按下鼠標或選擇某個菜單項時應該採取什麼行動。
在java.swing包中有一個Timer類,可以使用它在達到給定的時間間隔時發出通告。例如,假如程序中有一個時鐘,就可以請求每秒鐘獲得一個通告,以便更新時鐘的錶盤。
在構造定時器時,需要設置一個時間間隔,並告之定時器,當達到時間間隔時需要做些什麼操作。
如何告之定時器做什麼呢?在很多程序設計語言中,可以提供一個函數名,定時器週期地調用它。但是,在Java標準類庫中的類採用的是面向對象方法。它將某個類的對象傳遞給定時器,然後,定時器調用這個對象的方法。由於對象可以攜帶一些附加的信息,所以傳遞一個對象比傳遞一個函數要靈活很多。
當然,定時器需要知道調用哪一個方法,並要求傳遞的對象所屬的類實現了java.awt.event包的ActionListener接口。
public interface ActionListener {
void actionPerformed(ActionEvent event);
}
當到達指定的時間間隔時,定時器就調用actionPerformed方法。
假設希望每隔10秒鐘打印一條信息“At the tone, the time is …”,然後響一聲,就應該定義一個實現ActionListener接口的類,然後將需要執行的語句放在actionPerformed方法中。
class TimePrinter implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("At the tone, the time is " + new Date());
Toolkit.getDefaultToolkit().beep();
}
}
接下來,構造這個類的對象,並將它傳遞給Timer構造器。
ActionListenere listener = new TimePrinter();
Timer t = new Timer(10000, listener);
Timer構造器的第一個參數是發出通告的時間間隔,它的單位是毫秒。這裏希望每隔10秒鐘通告一次。第二個參數是監聽器對象。
最後,啓動定時器:
t.start();
實例
這個程序將彈出一個消息對話框,並等待用戶點擊OK按鈕來終止程序的執行。在程序等待用戶操作的同時,每隔10s顯示一次當前的時間。
運行這個程序時要有一些耐心。程序啓動後,將會立即顯示一個包含“Quit program?”字樣的對話框,10秒鐘之後,第1條定時器消息纔會顯示出來。
package cn.freedompc.timer;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.JOptionPane;
import javax.swing.Timer;
public class TimerTest {
public static void main(String[] args) {
ActionListener listener = new TimePrinter();
Timer t = new Timer(10000, listener);
t.start();
JOptionPane.showMessageDialog(null, "Quit program?");
System.exit(0);
}
}
class TimePrinter implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("At the tone, the time is " + new Date());
Toolkit.getDefaultToolkit().beep();
}
}
結果:
Comparator接口
我們之前已經瞭解瞭如何對一個對象數組排序,前提是這些對象是實現了Comparable接口的類的實例。例如,可以對一個字符串數組排序,因爲String類實現了Comparator<String>,而且,String.compareTo方法可以按字典順序比較字符串。
現在假設我們希望按長度遞增的順序對字符串進行排序,而不是按字典順序進行排序。肯定不能讓String類用兩種不同的方式實現compareTo方法,更何況,String類也不應由我們來修改。
要處理這種情況,Arrays.sort方法還有第二個版本,有一個數組和一個比較器(comparator)作爲參數,比較器是實現了Comparator接口的類的實例。
public interface Comparator<T> {
int compara(T first, T second);
}
要按長度比較字符串,可以如下定義一個實現Comparator<String>的類:
class LengthComparator implements Comparator<String> {
public int compare(String first, String second) {
return first.length - second.length();
}
}
具體完成比較時,需要建立一個實例:
Comparator<String> comp = new LengthComparator();
if (comp.compare(words[i], words[j]) > 0) ...
將這個調用與words[i].compareTo(words[j])做比較。這個compare方法在比較器對象上調用,而不是在字符串本省上調用。
捐贈
若你感覺讀到這篇文章對你有啓發,能引起你的思考。請不要吝嗇你的錢包,你的任何打賞或者捐贈都是對我莫大的鼓勵。