Java. Полное руководство. 8-е издание. С. Н. Тригуб Перевод с английского и редакция
Скачать 25.04 Mb.
|
import java.util.*; import java.io.*; class AvgFile { public static void main(String a r g s []) throws IOException { int count = 0; double sum = 0.0; // Записать вывод в файл fout = new FileWriterCtest.txt"); fout.write("2 3.4 5 6 7.4 9.1 10.5 готово fout.c l o s e (); Глава 18. Пакет java.util: прочие служебные классы 5 8 5 FileReader fin = new FileReader("Test.tx t "); Scanner src = new Scanner(fin); // Читать и суммировать значения w h i l e (s r c .h a sNext()) { if(src.hasNextDouble()) { sum += src.nextDouble(); count++; } else { String str = s r c .n e x t (); готово) break; else { System.out.p r Ошибка формата файла return; } } } s r c .c l o s e (Среднее равно " + sum / Вот вывод. Среднее равно Приведенная выше программа иллюстрирует другое важное средство класса S c a n n e r . Обратите внимание на то, что считыватель файла, упомянутый как f i n , не закрывается непосредственно. Вместо этого он автоматически закрывается, когда объект s r c вызывает метод c l o s e ( ) . Когда вы закрываете объект класса S c a n n e r , связанный с ним объект интерфейса также закрывается (если он реализует интерфейс. Поэтому в данном случае файл, упомянутый как f i n , автоматически закрывается, когда закрывается объект s r c Начиная с JDK 7 класс S c a n n e r реализует также интерфейс. Это означает, что им может управлять блок t r y - с ресурсами Как описано в главе 13, когда используется оператор t r y - с - ресурсами сканер автоматически закрывается в конце блока. Например, объектом s r c в приведенной выше программе можно управлять так (Scanner src = new Scanner(fin)) { // Читать и суммировать числа str = src.nextO; готово) break; else Ошибка формата файла Чтобы продемонстрировать закрытие объекта класса S c a n n e r , следующие примеры вызовут метод c l o s e () явно. Это позволяет им также компилироваться 5 8 6 Часть II. Библиотека версиями Java до JDK 7. Однако подход с оператором t r y - с - ресурсами проще и может помочь предотвратить ошибки. Его использование рекомендуется для нового кода. Еще один момент чтобы сохранить компактность этого и других примеров в данном разделе, исключения ввода-вывода просто передаются из метода m ain (). Однако ваш реальный код обычно будет обрабатывать исключения ввода-вывода самостоятельно. Вы можете использовать объект класса S c a n n e r для чтения ввода, который содержит некоторые различные типы данных, даже если порядок их следования заранее неизвестен. Вы просто должны проверять, какого типа доступны данные, прежде чем читать их. Например, рассмотрим следующую программу. //•Применение Scanner для чтения данных разного типа из файла import java.util.*; import java.io.*; class ScanMixed { public static void main(String a r g s []) throws IOException { int i ; double d; boolean b; String str; // Писать вывод в файл fout = new FileWriter("tes t Тестирование Scanner 10 12.2 один true два false"); fout.c l o s e (); FileReader fin = new FileReader("T e s t .txt"); Scanner src = new Scanner(fin); // Читать до конца w h i l e (s r c .hasNext()) { i f (s r c .hasNextlnt()) { i = s r c .nextInt(); System.out.println("i n t : " + i); } else i f (s r c .hasNextDouble()) { d = s r c .nextDouble(); System.out.p r i ntln("double: " + d ) ; } else i f (s r c .hasNextBoolean()) { b = s r c .nextBoolean(); System.out.println("boolean: " + b ) ; } else { str = s r c .n e x t (); System.out.println("String: " + str); s r c .c l o s e (Ниже показан результат Тестирование String: Scanner int: 10 double: 12.2 Глава 18. Пакет java.util: прочие служебные классы 8 7 String: один boolean: true String: два boolean: При чтении данных смешанных типов, как это делает предыдущая программа, следует быть немного внимательнее относительно порядка, в котором вызываются методы n e x t . Например, если в цикле поменять порядок вызовов методов n e x t I n t () и n e x t D o u b l e ( ) , то оба числовых значения будут прочитаны как тип d o u b l e , поскольку метод n e x t D o u b l e () соответствует любой строке, содержащей число, которое может быть интерпретировано как тип d o u b l e Установка разделителей Класс S c a n n e r определяет, где начинаются и заканчиваются лексемы, на основе набора разделителей По умолчанию разделителями являются пробельные символы, и именно этот набор разделителей используется в предыдущем примере. Однако можно изменить разделители, вызвав метод u s e D e l i m i t e r s ( ) , показанный ниже useDelimiter(String шаблон useDelimiter(Pattern шаблон) Здесь шаблон это регулярное выражение, которое определяет набор разделителей. Ниже показана измененная версия приведенной ранее программы, которая читает список чисел, разделенных запятыми и любым количеством пробелов Применение Scanner для вычисления среднего в списке Ч разделенных запятыми значений java.util.*; import java.io.*; class SetDelimiters { public static void main(String a r g s []) throws IOException { int count = 0; double sum = 0.0; // Писать вывод в файл fout = new FileWriter("test.tx t "); // Теперь сохранить значения в списке, разделенном запятыми fout.write("2, 3.4, 5,6, 7.4, 9.1, 10.5, готово fout.c l o s e (); FileReader fin = new FileReader("Test.txt"); Scanner src = new Scanner(fin); // Установить в качестве разделителей запятые и пробелы s r c .useDelimiter(", *"); // Читать и суммировать значения while(src.hasNext()) { if(src.hasNextDouble()) { sum += s r c .nextDouble(); count++; } else { String str = src.next(); i f (s t r готово) break; else Ошибка формата файла return; 5 8 Часть II. Библиотека Java } } s r c .c l o s e (Среднее равно " + sum / В этой версии числа, записанные в файл t e s t . t x t , разделены запятыми и пробелами. Применение шаблона разделителей " , *" сообщает объекту класса S c a n n e r , чтобы он воспринимал запятую и ноль в качестве разделителей. Вывод программы будет таким же, что и ранее. Вы можете получить текущий шаблон разделителей вызовом метода d e l i m i t e r ( ) , показанного ниже Прочие возможности класса S c a n n e Класс S c a n n e r определяет несколько других методов в дополнение к уже упомянутым. В частности, одним из наиболее часто используемых в некоторых случаях является метод f i n d l n L i n e ( ) . Его общие формы представлены ниже findlnLine(Pattern шаблон findlnLine(String шаблон) Этот метод ищет указанный шаблон внутри следующей строки текста. Если шаблон найден, соответствующая ему лексема принимается и возвращается. В противном случае возвращается значение n u l l . Метод работает независимо от набора разделителей. Этот метод удобен, если требуется специфический шаблон. Например, следующая программа ищет поле возраста во входной строке и затем отображает его Демонстрация применения findlnLine(). import java.util.*; class FindlnLineDemo { public static void main(String a r g s []) { String instr = "Имя Том Возраст 28 ID: 77"; Scanner conin = new Scanner(instr); // Найти и отобразить возраст. conin.findlnLine("Возраст:"); // найти "Возраст i f (conin.hasNext()) System.out.println(conin.next()); else System.out.p r Ошибка Результатом будет 2 8. В программе метод f i n d l n L i n e () применяется для поиска вхождения шаблона " Возраст. Когда он найден, читается следующая лексема, которая представляет собой значение возраста. С методом f i n d l n L i n e ( ) связан метод f i n d W i t h i n H o r i x o n () . String findWithinHorizon(Pattern шаблон int количество findWithinHorizon(String шаблон int количество) Этот метод пытается найти вхождение указанного шаблона в следующие количество символов. В случае успеха метод возвращает совпадающий шаблон, в противном случае — значение n u l l . Если параметр количество содержит значение нуль, то поиск выполняется во всем вводе до тех пор, пока либо не будет обнаружено совпадение, либо не будет достигнут конец входной информации Глава 18. Пакет java.util: прочие служебные классы 5 8 Вы можете пропустить шаблон, используя метод s k i p (). Scanner skip(Pattern шаблон skip(String шаблон) Если соответствие шаблону имеется, метод skip () просто пропускает его и возвращает ссылку на вызывающий объект. Если шаблон не найден, метод skip () передает исключение NoSuchElementExcept К другим методам класса Scanner относятся метод radix () , который возвращает основание системы счисления по умолчанию, используемое классом Scanner при чтении чисел метод useRadix(), который устанавливает основание системы счисления метод reset ( ), который сбрасывает сканер и метод close () , закрывающий сканер. Классы ResourceBundlep ListResourceBundle и Пакет java.util включает три класса, предназначенные для интернационализации ваших программ. Первый из них — абстрактный класс ResourceBundle. Он определяет методы, позволяющие управлять коллекцией чувствительных к региональным данным ресурсов, таких как строки, используемые в качестве меток элементов пользовательского интерфейса программ. Вы можете определить два или более наборов переведенных строк, поддерживающих различные языки, скажем, английский, немецкий или китайский, причем каждый перевод будет находиться в собственной связке (bundle). Затем вы можете загружать нужную связку в соответствии с текущими локальными установками и использовать строки для создания пользовательского интерфейса программы. Связки ресурсов идентифицируются именем семейства (также называемыми их базовыми именами К имени семейства может быть добавлен двухсимвольный код языка, указывающий на конкретный язык. В этом случае, если запрошенные региональные данные соответствуют коду языка, используется эта версия связки ресурсов. Например, связка ресурсов с именем семейства SampleRB может иметь немецкую версию SampleRB_de и русскую версию SampleRB_ru. Обратите внимание знак подчеркивания связывает имя семейства с кодом языка) Таким образом, если текущими региональными данными есть Locale . GERMAN, будет применяться связка Также можно указать специфические варианты языка, которые относятся к определенной стране, указывая код страны после кода языка. Код страны — это двухсимвольный идентификатор в верхнем регистре, такой как AU для Австрии или IN для Индии. Коду страны также предшествует знак подчеркивания, когда он связывается с именем связки ресурсов. Связка ресурсов, имеющая только имя семейства, применяется по умолчанию. Она используется, когда недоступны специфичные для языка связки. На заметку Коды языков определены стандартом ISO 639, а коды стран стандартом ISO Методы, определенные в классе ResourceBundle, перечислены в табл. 18.19. Одно важное замечание пустые ключи не допускаются, а потому несколько методов передают исключение NullPointerException, если получают пустой ключ. Следует обратить внимание на вложенный класс ResourceBundle. Control. Он добавлен в Java SE 6 и используется для управления процессом загрузки связок ресурсов Таблица 18.19. Методы, определенные в классе R e s o u r c e B u n d l e 5 9 0 Часть II. Библиотека Метод Описание final void c l e a r C a c h e O Удаляет все связки ресурсов из кеша, которые были загружены загрузчиком классов по умолчанию final void Удаляет все связки ресурсов из кеша, которые (ClassLoader за гр были загружены загрузчиком за гр к) Возвращает значение true, если к — ключ внутри вызывающей связки ресурсов (или ее родителя final ResourceBundle Загружает связку ресурсов с именем семейства getBundle ( String имя Семейства) имяСемейства, используя региональные данные и загрузчик классов по умолчанию. Передает исключение MissingResourceException, если не найдено связки ресурсов, соответствующей имени имяСемейства Загружает связку ресурсов с именем семейства имяСемейства , используя указанные региональные данные и загрузчик классов по умолчанию. Передает исключение Miss ingResourceExcept ion, если не найдено связки ресурсов, соответствующей имени имяСемейства Загружает связку ресурсов с именем семейства имя Семейства, используя указанные региональные данные и загрузчик классов. Передает исключение M i если не найдено связки ресурсов, соответствующей имении м яСем ейства Загружает связку ресурсов с именем семейства имяСемейства , используя региональные данные и загрузчик классов по умолчанию. Процесс загрузки находится под управлением контроль. Передает исключение MissingResourceException, если не найдено связки ресурсов, соответствующей имени имяСемейства Загружает связку ресурсов с именем семейства имяСемейства , используя указанные региональные данные и загрузчик классов по умолчанию. Процесс загрузки находится под управлением контроль. Передает исключение MissingResourceException, если не найдено связки ресурсов, соответствующей имени имяСемейства Загружает связку ресурсов с именем семейства имяСемейства , используя указанные региональные данные и загрузчик классов. Процесс загрузки находится под управлением контроль. Передает исключение Mi ss ingResourceExcept ion, если не найдено связки ресурсов, соответствующей имени имяСемейства abstract Возвращает ключи связки ресурсов как перечисление строк. Любые родительские ключи также возвращаются getLocale() Возвращает региональные данные, поддерживаемые связкой ресурсов ResourceBundle g e t B u n d l e (String имя Семейства регион за гр контроль им яСемейства, Locale регион контроль имяСем ей ства , Locale регион имя Семейства регион загр) static final ResourceBundle g e t B u n d l e (String имя Семейства контроль Глава 18. Пакет java.util: прочие служебные классы 9 Окончание табл. 18.19 Мекэд Описание final Object getObject(String k) final String getString(String k) final S t r i n g [] g e t S t r i n g A r r a y (String k) protected abstract Object handleGetObject(String k) protected Set h a n d l e K e y S e t () Set protected void setParent(ResourceBundle родитель ский) Возвращает объект, ассоциированный с ключом, переданным параметром к Передает исключение MissingResourceException, если к не найден в связке ресурсов Возвращает строку, ассоциированную с ключом, переданным параметром к Передает исключение MissingResourceException, если к не найден в связке ресурсов. Передает исключение ClassCastException, если объект, ассоциированный с к, не является строкой Возвращает массив строк, ассоциированных с ключом, переданным параметром к Передает исключение MissingResourceExcept ion, если к не найден в связке ресурсов. Передает исключение если объект, ассоциированный с к не является массивом строк Возвращает объект, ассоциированный с ключом, переданным параметром к Возвращает значение nul 1, если к не найден в связке ресурсов Возвращает ключи связки ресурсов как набор. Родительские ключи не извлекаются. Также не возвращаются ключи со значениями Возвращает ключи связки ресурсов как набор строк. Родительские ключи также извлекаются Устанавливает родительский как родительскую связку для данной связки ресурсов. Если ключ не найден в вызывающем ресурсном объекте, поиск продолжится в родительском объекте___________ У класса ResourceBundle есть два подкласса. Первый из них — класс FropertyResourceBundle, управляющий ресурсами через файлы свойств. Этот класс не добавляет собственных методов. Второй — это абстрактный класс List ResourceBundle, управляющий ресурсами в массиве пар “ключ-значение”. Этот класс добавляет метод get Contents (), который должны реализовать все подклассы. Выглядит он так. protected abstract 0bject[][] Этот класс возвращает двухмерный массив, содержащий пары “ключ-значение”, представляющие ресурсы. Юпочи могут быть строками. Значения — обычно строки, но могут быть и объектами других типов. Рассмотрим пример, демонстрирующий использование связки ресурсов. Связка ресурсов имеет имя семейства SampleRB. Два класса связок ресурсов этого семейства создаются расширением класса List ResourceBundle. Первый называется SampleRB и представляет собой связку по умолчанию для английского языка java.util.*; public class SampleRB extends ListResourceBundle { protected Ob j e c t [][] getContents() { 0bject[][] resources = new Ob j e c t [3][2]; resources[0][0] = "title"; resources[0][1] = "My Program" 5 9 2 Часть II. Библиотека Java resources[1][0] resources[13 [1] resources[2][0] resources[2][1] "StopText"; "Stop"; "StartText" "Start"; return Вторая связка ресурсов, показанная ниже, называется Sam pleRB_de и сдержит немецкий перевод java.util.*; // Немецкоязычная версия class SampleRB_de extends ListResourceBundle { |