Назад | Начало урока | Вперед
Содержание

Глава 06


Программа 06_08 Converter

Задача: Необходимо обеспечить возможность просмотра курса ZAR(южно-африканские рэнды) к валютам разных стран и конвертирования валюты.

Решение: У нас имеется таблица данных в текстовом файле rates.dat .

Код _ Страна _ Валюта _ _ _ _ _ _ _ ZAR/единица(валюты) _ _ Единица/ZAR

Подсказка

В каждом ряду таблицы содержатся пять значений -
код, название страны, название валюты и два курса для обмена.

Мы введем все значения из текстового файла в хеш-таблицу, ряд за рядом, а затем будем обращаться к ней, используя ключ, которым является название страны (второе поле).

Создадим класс для хранения совокупности полей одной строки. Этот класс изначально будет предназначен для приема и хранения данных. Поэтому класс должен иметь метод для ввода данных в поля из текстового файла.

class Rates {

String country;
String code;
String currency;
double conversion;

void setRate (Stream in) throws IOException {

code = in.readString();
country = in.readString();
currency = in.readString();
// we don't want the first rate,
// ignore it by reading over it
conversion = in.readDouble();
conversion = in.readDouble();
}
}

Этот класс содержит наименование страны, код валюты, наименование валюты и два курса обмена.

Класс имеет метод setRate, который заполняет все поля данными, считанными из текстового файла. Мы должны передать в параметр поток считывания in типа Stream.

Каждый объект класса Rates содержит в себе одну строку из текстового файла. Где же мы будем сохранять множество объектов этого класса?

Это множество объектов мы будем сохранять в объекте класса Hashtable (это хэш-таблица).
Ключом в этой хэш-таблице будет название страны (country).

Класс Hashtable входит в пакет java.until, поэтому мы не имеем доступа к его структуре, но знаем, что он содержит ключи и значения. Ключи в таблице - это объекты класса String, а значения - объекты класса Rates.

Теперь посмотрим программу:

class Converter {

Создадим объект display типа Display для интерактивного общения с пользователем.
Затем создадим объект table типа Hashtable для хранения экземпляров класса Rates в качестве значений и объектов типа String в качестве ключей.

Display display = new Display ("Currency Converter");
Hashtable table = new Hashtable();

Converter () throws IOException {

initialise();
readIn();
echo();
transactions();
}

Затем в конструкторе мы видим четыре функции.



Рассмотрим интересную функцию, при помощи которой инициализируется хеш-таблица типа Hashtable значениями, считанными из текстового файла.

Посмотрим функцию readIn() :

void readIn() throws IOException {

Rates rate;
String filename = display.getString("Rates file");
Stream fin = Filer.open(filename);
try {
for (int i = 0; ; i++) {
rate = new Rates();
rate.setRate(fin);
table.put(rate.country, rate);
}
}
catch (EOFException e) {
display.println("Data read in and stored\n");
}
}

Сначала с экрана считывается из элемента типа TextField название текстового файла, из которого надо считывать данные в хэш-таблицу.

String filename = display.getString("Rates file");

Затем название этого текстового файла передается в параметр методу open класса Filter, который считывает данные в поток fin типа Stream :

Stream fin = Filer.open(filename);

Затем из потока построчно в цикле считываются данные в экземпляры класса Rates, и эти экземпляры сохраняются в хэш-таблице table. Данные считываются в поля экземпляра класса Rates при помощи функции setRate.

for (int i = 0; ; i++) {

rate = new Rates();
rate.setRate(fin);
table.put(rate.country, rate);
}

Данные из потока считываются до тех пор. пока не будет достигнут конец файла. По окончанию файла вызывается исключение, которое сообщает пользователю, что данные считаны и сохранениы в хэш-таблице.

catch (EOFException e) {

display.println("Data read in and stored\n");
}

Повторяю, что в хэш-таблицу записываются поле country в качестве ключа и экземпляр rate
класса Rates в качестве значения.

table.put(rate.country, rate);

И так, в каждой итерации цикла for создается новый объект rate класса Rates, затем с помощью функции setRate() заполняются поля этого объекта, ну а затем с использованием этого объекта заполняются поля хэш-таблицы table.

Повторим какая происходит такая цепочка событий:

С текстового файла считывается в поток Stream
Далее цикл:
Из потока Stream считывается в объект типа Rates
Из объекта типа Rates в хэш-таблицу

Теперь, когда данные из текстового файла считаны в хэш-таблицу, с ней можно работать.


Далее посмотрим функцию echo:

void echo() {

display.println("In the table");
int i = 1;
for (Enumeration e = table.keys(); e.hasMoreElements(); i++) {
String country = (String)e.nextElement();
display.println(country);
}
}

Эта функция выводит на экран названия стран из хэш-таблицы. По сути дела она выводит названия ключей хэш-таблицы. Как видим эта функция показывает нам метод обращения к хэш-таблице и извлечение из нее данных:

for (Enumeration e = table.keys(); e.hasMoreElements(); i++) {

String country = (String)e.nextElement();

Запомни хорошо эти две строки!


Теперь посмотрим функцию transactions():

void transactions () {

display.prompt("Country", "American");
display.prompt("Amount", 1000);
String country;
double amount;
String c;
Rates r;

while (true) {

display.println("Scroll up to see countries");
display.ready("Enter country and amount and press ready");
c = display.getString("Country");
if (table.containsKey(c)) {
amount = display.getDouble("Amount");
r = (Rates) table.get(c);
display.println( Stream.format(amount,6,2) +" ZAR in "+c+" "
+r.currency+" is "+
Stream.format(amount * r.conversion,6,2)+"\n");
}
else {
display.println("Sorry, country "+c+" not in table\n");
}
} // while
} // transactions



Анализ:

Эта функция сначала вводит в окно два новых управляющих элемента типа TextField
мы видим в параметрах указаны их имена и значения.

display.prompt("Country", "American");
display.prompt("Amount", 1000);

Имея имя и значение, мы можем в программе считать из этих полей ввода те значения, которые введет пользователь. А по умолчанию пока введены значения, которые мы здесь видим.

Далее объявляется ряд локальных переменных:

String country;
double amount;
String c;
Rates r;

Затем в цикле while выводится предложение для пользователя прокрутить при помощи линейки прокрутки (ScrollBar) страницу, чтобы увидеть названия всех стран, а так же ввести данные в поля, а именно название страны и величину(сумму) которую надо конвертировать.

while (true) {

display.println("Scroll up to see countries");
display.ready("Enter country and amount and press ready");

Затем идет считывание из полей ввода:

c = display.getString("Country");
if (table.containsKey(c)) {

amount = display.getDouble("Amount");

Название страны сохраняется в переменной c типа String, а значение для конвертирования сохраняется в переменной amount типа double. При этом учитывается условие if (table.containsKey(c)) Если хэш-таблица содержит название ключа ( в нашем случае это название страны), то есть если это название не пусто, и что это название совпадает с названием, которое пользователь ввел в поле ввода.
В противном случае:

else {

display.println("Sorry, country "+c+" not in table\n");
}

Здесь опять тот случай, когда мы обращаемся к хэш-таблице, чтобы посмотреть список ее ключей, и проверить содержится ли в ее списке ключей выбранное слово.

Если содержится то выбираем значение, которое содержится под этим ключем, в данном случае это объект типа Rates. Берем это значение из таблицы и присваиваем его переменной r типа Rates, предварительно приведя полученное значение к этому типу.

r = (Rates) table.get(c);

Получив значение экземпляра класса Rates из хэш-таблицы, мы можем манипулировать с его полями, что мы и делаем в следующей иснтрукции

display.println( Stream.format(amount,6,2) +" ZAR in "+c+" "

+r.currency+" is "+
Stream.format(amount * r.conversion,6,2)+"\n");

На экране получится примерно следующее

"Введенная сумма (допустим 500)" Zar in "Название страны и валюты (допустим японские йены)" is Далее идет значение вычисленное по формуле произведения введенной суммы на коэффициент конвертации

amount * r.conversion

Здесь r.conversion это поле экземпляра класса Rates, а этот экземпляр мы получили из хэш-таблицы.

Вот результат на экране:

500,00 ZAR in Japanese Yen is 12775,00

Далее как обычно идет главная функция:

public static void main(String[] args) throws IOException {

Converter data = new Converter ();
}

} // class Converter

Код программы:


import java.io.*;
import javagently.*;
import java.util.*;
import myutilities.*;

class Converter {

/* The Converter Program by J M Bishop Dec 1998
* --------------------- updated June 2000
* Keeps the exchange rates from one currency into
* many others and enables currency purchases to be
* estimated.
*
* Illustrates the use of hash tables.
*/

Display display = new Display ("Currency Converter");
Hashtable table = new Hashtable();

Converter () throws IOException {

initialise();
readIn();
echo();
transactions();
}

// read in each line of data and store in
// the hash table with country as key

void initialise () {

display.println("Currency Converter\n"+
"==================");
display.prompt("Rates file", "rates.dat");
display.ready("Press ready when the file is ok");
}

void readIn() throws IOException {

Rates rate;
String filename = display.getString("Rates file");
Stream fin = Filer.open(filename);
try {
for (int i = 0; ; i++) {
rate = new Rates();
rate.setRate(fin);
table.put(rate.country, rate);
}
}
catch (EOFException e) {
display.println("Data read in and stored\n");
}
}

void echo() {

display.println("In the table");
int i = 1;
for (Enumeration e = table.keys(); e.hasMoreElements(); i++) {
String country = (String)e.nextElement();
display.println(country);
}
}

void transactions () {

display.prompt("Country", "American");
display.prompt("Amount", 1000);
String country;
double amount;
String c;
Rates r;

while (true) {

display.println("Scroll up to see countries");
display.ready("Enter country and amount and press ready");
c = display.getString("Country");
if (table.containsKey(c)) {
amount = display.getDouble("Amount");
r = (Rates) table.get(c);
display.println( Stream.format(amount,6,2) +" ZAR in "+c+" "
+r.currency+" is "+
Stream.format(amount * r.conversion,6,2)+"\n");
}
else {
display.println("Sorry, country "+c+" not in table\n");
}
} // while
} // transactions

public static void main(String[] args) throws IOException {

Converter data = new Converter ();
}

} // class Converter

Подсказка

Рис 6.18 Интерфейс класса Display для программы "Конвертер валют"


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz