|
Java中利用散列表實(shí)現(xiàn)股票行情的查詢 建設(shè)銀行云南省保山地區(qū)分行 楊紹方 ---- 在java中,提供了一個(gè)散列表類Hashtable,利用該類,我們可以按照特定的方式來存儲數(shù)據(jù),從而達(dá)到快速檢索的目的。本文以查詢股票的收盤數(shù)據(jù)為例,詳細(xì)地說明java中散列表的使用方法。
一、散列表的原理 ---- 散列表,又稱為哈希表,是線性表中一種重要的存儲方式和檢索方法。在散列表中,可以對節(jié)點(diǎn)進(jìn)行快速檢索。散列表算法的基本思想是:由結(jié)點(diǎn)的關(guān)鍵碼值決定結(jié)點(diǎn)的存儲地址,即以關(guān)鍵碼值k為自變量,通過一定的函數(shù)關(guān)系h(稱為散列函數(shù)),計(jì)算出對應(yīng)的函數(shù)值h(k)來,將這個(gè)值解釋為結(jié)點(diǎn)的存儲地址,將結(jié)點(diǎn)存入該地址中,檢索時(shí),根據(jù)要檢索的關(guān)鍵碼值,用同樣的散列函數(shù)計(jì)算出地址,然后,到相應(yīng)的地址中去獲取要找的結(jié)點(diǎn)數(shù)據(jù)。因此,散列表有一個(gè)重要特征:平均檢索的長度不直接依賴于表中元素的個(gè)數(shù)。 ---- 散列表最重要的一個(gè)指標(biāo)是負(fù)載因子,即散列表中結(jié)點(diǎn)數(shù)目與表中能容納的總結(jié)點(diǎn)數(shù)的比值,它描述了散列表的飽和程度,負(fù)載因子越接近1.0,內(nèi)存的使用效率越高,元素的尋找時(shí)間越長,同樣,負(fù)載因子越接近0.0,元素的尋找時(shí)間越短,但內(nèi)存的浪費(fèi)越大。Hashtable類缺省的負(fù)載因子為0.75.
二、Hashtable類 ---- Hashtable類為我們提供了散列表完整的功能,可以讓我們很方便地構(gòu)造和使用散列表,查詢信息。 ---- 1.創(chuàng)建散列表對象
---- Hashtable類的構(gòu)造器主要有下面幾種形式:
public Hashtable(int initialCapacity, float loadFactor); public Hashtable(int initialCapacity); public Hashtable(); 在本文的實(shí)例中,我們使用了最簡單的一種: Hashtable stockInfo = new Hashtable();
---- 2.充填數(shù)據(jù) ---- 當(dāng)構(gòu)造了Hashtable對象后,我們就可以將數(shù)據(jù)填入該對象中,以便以后查詢。Hashtable類提供了put方法來完成數(shù)據(jù)的裝填,其原型如下:
---- public synchronized Object put(Object key, Object value);
---- 3.查詢數(shù)據(jù)
---- 查詢數(shù)據(jù)可以使用get方法,其原型如下:
---- public synchronized Object get(Object key)
---- 4.其它常用的方法
public int size(); //返回散列表中的結(jié)點(diǎn)數(shù)目 public boolean isEmpty(); //判斷散列表是否為空 public boolean containsValue(Object value); //判斷散列表中是否含有某值 public synchronized boolean containsKey(Object key); //判斷散列表中是否含有某個(gè)結(jié)點(diǎn) public synchronized void clear(); //清空整個(gè)散列表
三、StringTokenizer類 ---- StringTokenizer類的主要用途是將字符串以定界符為界,分析為一個(gè)個(gè)的token(可理解為單詞),定界符可以自己指定。 ---- 構(gòu)造器有下面幾種形式:
public StringTokenizer(String str, String delim, boolean returnTokens); public StringTokenizer(String str, String delim); public StringTokenizer(String str); 其中,str為需分析的字符串,delim為定界符, Tokens描述是否將定界符作為一個(gè)token。
---- 其它常用的方法有: public boolean hasMoreTokens() ; //判斷字符串中是否還有token public String nextToken();// StringTokenizer對象的下一個(gè)token
四、實(shí)例 ---- 本文使用的股票行情為上海和深圳證券交易所的收盤行情,文件名為hqsj.txt,下面是文件中的一行數(shù)據(jù): ---- 600122宏圖高科 18.90 18.80 18.90 18.20 18.27 3155 582.96
---- 下面是完整的源程序,在JDK1.2下使用javac編譯通過。
import java.io.*; import java.util.*; import java.awt.*; import java.applet.*; import java.awt.event.*;
public class StockQuote extends Applet implements ActionListener { private static final File INFO_FILE = new File("hqsj.txt"); private Hashtable stockInfo; TextField stockID; Button button1; private String quoteid,quotename;
public void init() { add(new Label("股票代碼")); stockID = new TextField(6); add(stockID); button1 = new Button("查詢"); button1.addActionListener(this); add(button1); resize(500, 300); }
public void start() { loadinfo(); }
protected boolean loadinfo() { String fileLine; StringTokenizer tokenize; String id; StringBuffer name;
try { // 創(chuàng)建一個(gè)訪問數(shù)據(jù)文件的stream BufferedReader stockInput = new BufferedReader(new FileReader(INFO_FILE)); // 創(chuàng)建Hashtable對象 stockInfo = new Hashtable(); // 每次從文件中讀一行數(shù)據(jù) while ((fileLine = stockInput.readLine()) != null) { // 將每一行數(shù)據(jù)分解為tokens. tokenize = new StringTokenizer(fileLine); try { id = tokenize.nextToken(); // 創(chuàng)建一個(gè)放置股票信息的buffer name = new StringBuffer(); while(tokenize.hasMoreTokens()) { name.append(tokenize.nextToken()); if (tokenize.hasMoreTokens()) { name.append(""); } } // 向Hashtable中充填記錄 stockInfo.put(id,name.toString()); } catch(NullPointerException excpt) { System.err.println("充填數(shù)據(jù)時(shí)出錯(cuò): " + excpt); } catch(NoSuchElementException excpt) { System.err.println("無效的數(shù)據(jù)記錄 " + "in file: " + excpt); } } stockInput.close();
} catch(FileNotFoundException excpt) { System.err.println("不能發(fā)現(xiàn)文件: " + excpt); return false; } catch(IOException excpt) { System.err.println("I/O故障: " + excpt); return false; } return true; }
protected String getQuote(String StockID) { String info;
// 從Hashtable得到數(shù)據(jù) info = (String)stockInfo.get(StockID); if (info != null) return info; else return "股票代碼錯(cuò)誤!"; }
public void paint(Graphics g) { g.drawString("股票代碼"+quoteid+":" ,10,60); g.drawString("股票名稱"+"前收"+"今開"+"最高" +"最低"+"收盤"+"交易量"+"交易金額", 10, 90); g.drawString(quotename, 10, 120); }
public void actionPerformed(ActionEvent ev) { String label = ev.getActionCommand(); if (label.equals("查詢")) { quoteid = stockID.getText(); if(quoteid != null) quotename = getQuote(quoteid); else quotename = "請輸入股票代碼!"; repaint(); } } }
---- 由于java固有的、安全方面的限制,如果不使用SecurityPermission或數(shù)字簽名等措施,java程序就不具有讀取本地文件的權(quán)限,為了節(jié)省篇幅,本文對此不再多做討論,將編譯得到的StockQuote.class放到一個(gè).html文件中,直接使用jdk1.2提供的appletviewer,其命令行的使用方法如下: d:\jdk1.2\bin\appletviewerStockQuote.html
|