藉一個排序實例認識 Java 環境
你手上的工作適合用 Java 解嗎?
Sun 的 Java 是現在當紅的語言, 除了獲得諸如 IBM 等大公司的 支持 之外, 自由軟體界也有 豐富的資源。
但筆者認為 java 紅得名過其實, 以致於許多人在不適當的場合誤用 java。 程式語言的優劣並不完全決定於它的功能是否強大; 常人往往忽略更重要的一點: 從學習到應用, 這個語言是否真的能夠提高程式設計師的生產力? 倚天劍與屠龍刀固然很酷, 我們不會拿它來切水果; 噴射機固然很酷, 到巷子口買早餐還是騎 腳踏車 比較方便。 更何況寶刀還有干將莫邪; 交通工具還有深海潛艇, 在不同的場合, 可能更適用。 最後, 還有一點政治因素, 請見 Richard Stallman 的文章: Free but shackled: The Java trap。
撇開政治不談, 純粹從技術角度來看, 我還是認為 java 並不適合日常生活使用。 即使是對資訊科系的同學而言, 拿它來當做入門的語言, 都嫌太沉重。 寫程式要有成就感才會有樂趣。 光是寫個 "hello world!" 就要先三跪九叩, 定義 class 與 method, 如果我第一個接觸的程式語言是 java, 老早就被嚇壞, 對寫程式完全喪失信心。 我很慶幸自己沒有生在盲目崇拜 java 的年代。
最值得資訊科系同學拿來入門, 最值得其他非資訊科系同學拿來玩票學寫程式的, 應該是 scripting 類的程式語言。 過去被 java 嚇到失去寫程式興趣與信心的同學, 建議從這類語言著手, 三五行就可以寫出有用的程式, 你會發現寫程式可以是很有成就感的事 (如果是 perl, 一句話就可以做很多有用的事)。 隔了很久以後, 也許你會發覺其實 java 的複雜設計確實有它的好處, 特別適用於撰寫龐大, 需要模組化的系統。
以下幾篇批評 java 的文章請參考:
- Why I am not a Java Programmer (或見 庫存頁面): 指出 java 與 perl 背後設計哲學的不同, 請讀者自行判斷選擇。 極佳文章。
- Softpanorama Java Critique Page: java 像 cobol 一樣, 不完美, 但符合商業需要, 所以比其他技術上更優秀的語言流行。
- A Java Critique: Java 較諸 C/C++ 的有餘與不足, 以及概括承受其既有缺點的沉重包袱。
有一類場合 java 倒是非常適合: 執行速度是重要考量, 程式碼會重複利用, 介面明確/簡單/清楚, 的函式庫。 具體地說, 資料結構就是一個使用 java 絕佳的場合。 這篇講義的目的就是為了配合資料結構課程, 介紹一下純自由軟體的 java 環境; 將來或許會增加其他話題。 但可以確定的是: 它永遠不會變成 java 入門的教學講義。 讀者必須先自行熟悉物件導向的觀念, 與 Java 語言基本要素。 (可是我自己也還沒有學 java 耶...)
呼應 rms 的觀點, 我們只推薦純自由軟體的 Java 環境。 至少有兩個選擇如下:
- 安裝 自由軟體基金會 (fsf) gnu 計劃的 gcj。 在 Mandrake Linux 上, 主要是 gcj-tools 與 gcc-java 兩個套件, 及其他一堆相依套件。
- 或是安裝 kaffe 作為 compiler 及 VM。 在 Mandrake Linux 上, 直接安裝 kaffe 套件就可以了。 雖然文件只說 kaffe 是一個 VM, 但其實它也可以編譯原始碼。
以下假設你已安裝好 gnu 版或 kaffe 版的 java。
實驗一: 編譯自己寫的軟體
- 編譯 FSUArray 函式庫:
javac FSUArray.java
並確認在目前目錄內產生了一個虛擬機器的機器碼檔 (byte code of the virtual machine) FSUArray.class 注意: 編譯時必須給副檔名! - 編譯 SortDemo 主程式:
javac SortDemo.java
並確認在目前目錄內產生了一個虛擬機器的機器碼檔 SortDemo.class 一樣, 編譯時必須給副檔名。 如果你用的是 gnu 版, 可能會出現 "找不到 FSUArray" 之類的訊息, 改試試看:javac -classpath . SortDemo.java
- 執行程式:
java SortDemo guava orange apple grape kiwi banana
應該印出排序後的結果, 每列一個字串。 注意: 執行時不可給副檔名!
如果是在 cygwin
底下使用 gcc-java, 下指令的方式有一點不同。 其實 gcj 是 gcc
的前置處理器, 所以最後透過 gcc 產生出來的是執行檔, 而不是 java byte
code。 例如你有一個 SetExample.java
程式, 可以這樣編譯: gcj --main=SetExample
SetExample.java
檢查一下, 發現產生了一個 a.exe 檔,
直接就可以執行: ./a.exe
實驗二: 使用既有函式庫的介面
同樣的程式碼, 但現在要改用 Williams 所定義的 PriorityQueue 介面。 請先下載威廉的函式庫 data-structures.jar, 放在某目錄底下。
- 刪除原有的 byte code:
rm *.class
- 按照註解修改 FSUArray.java (兩處) 及 SortDemo.java (兩處)
- 重新編譯:
javac FSUArray.java
注意看看有什麼錯誤訊息? - 把 Williams 寫的函式庫, 及目前目錄, 都加入搜尋路徑:
export CLASSPATH=某目錄/data-structures.jar:.
注意最後面的句點不要打漏了, 這代表 "目前目錄"。 而且全部打在同一列上, 除了 export 與 CLASSPATH 之間有一個空格, 其他地方都不能有空格。 如果是 kaffe 版, 還要將系統內定的函式庫路徑也一併寫出來:export CLASSPATH=/usr/lib/kaffe/lib/rt.jar:某目錄/data-structures.jar:.
這句 export 只要下一次, 就相當於每次在命令列上給 -classpath 這個選項, 省去編譯時的麻煩。 但是如果離開 shell, 下次再進來時, 還是必須再打一次。 若將這句話放在 .bashrc 裡面, 就可以一勞永逸。 - 編譯 FSUArray 函式庫:
javac FSUArray.java
產生 FSUArray.class 這個虛擬機器碼檔案。 如果是 kaffe 版, 會自動放在 DataStructures/ 子目錄底下; 如果是 gnu 版, 則是放在目前目錄下, 請手動建立子目錄並將檔案搬進去, 不然等一下執行時會出錯。 - 編譯 主程式:
javac SortDemo.java
產生 SortDemo.class 檔案。 - 執行程式:
java SortDemo guava orange apple grape kiwi banana
應該印出排序後的結果, 每列一個字串。
實驗三: 使用既有函式庫的實作
這次我們不只使用 Williams 所寫的 PriorityQueue 介面, 還要使用他所寫的 BinaryHeap 類別。 (不論新增或刪除都不花太多時間, 一個很有效率的類別。) 至於我們自己寫的 FSUArray 將被我們抽換掉, 完全用不到了。
- 刪除 FSUArray.class, 再執行一次 SortDemo, 應該會出錯。 請仔細看: 錯誤訊息說什麼?
- 把這句
PriorityQueue pq = (PriorityQueue) new FSUArray();
裡面的 FSUArray 改成 BinaryHeap - 重新編譯, 再執行一次。
實驗四: 如果要對複雜的資料結構排序呢?
假設我們要對 學生成績 排序。 請編譯並執行 CmpDemo.java。 現在你的程式到底用到那些類別呢? FSUArray.java 還有用到嗎?
作業:
- 請寫一個類別 SortedArray 用以取代 FSUArray。 裡面的資料由大到小按順序排列, 新增時必須視資料大小將之安插到正確位置; 刪除時則永遠刪除並傳回最小, 也就是最後面那個元素。 一樣用 SortDemo 程式測試你的類別, 先只使用 SortDemo 與 SortedArray; 再改採用 Williams 所寫的 PriorityQueue 介面, 重新編譯/執行一次。
-
有書籍資料數筆, 包含書名, 作者, 價格, 頁數等資訊, 例如:
Perl 學習手冊 第三版, Randal L. Schwartz and Tom Phoenix, 580 元, 380 頁 Perl程式設計疑難排解, Martin Brown, 490 元, 512 頁 ... Advanced Perl Programming, Sriram Srinivasan, 1225 元, 427 頁
請模仿實驗四, 寫一個程式 (實際上是兩個 .java 檔) 對這些書本按照 「每頁的價格」 排序。 (當然這個順序與書籍的好壞沒有特別的關係; 只是隨便舉的例子)
- 本頁最新版網址: https://frdm.cyut.edu.tw/~ckhung/b/pr/java.php; 您所看到的版本: February 14 2012 10:32:25.
- 作者: 朝陽科技大學 資訊管理系 洪朝貴
- 寶貝你我的地球, 請 減少列印, 多用背面, 丟棄時做垃圾分類。
- 本文件以 Creative Commons Attribution-ShareAlike License 或以 Free Document License 方式公開授權大眾自由複製/修改/散佈。