10, 20, Этот код порождает такую строку 10 В этом примере первый спецификатор формата соответствует 30, второй — 10, а третий — 20. То есть аргументы используются в порядке, отличном от простого порядка слева направо”. Одним из преимуществ индексирования аргументов является то, что это позволяет повторно использовать аргумент, не указывая его дважды. Например, строка в шестнадцатеричном формате равно х порождает следующий результат 55 в шестнадцатеричном формате равно Как видите, аргумент 255 используется с обоими спецификаторами формата. Существует удобное сокращение, называемое относительным индексом, которое позволяет повторно использовать аргументы, соответствующие предшествующему спецификатору формата. Просто укажите < вместо индекса аргумента. Например, следующий вызов метода f o r m a t () порождает тот же результат, что и предыдущий пример в шестнадцатеричном формате равно х Относительные индексы особенно удобны при создании пользовательских форматов времени и даты. Рассмотрим следующий пример Использование относительных индексов для упрощения // создания пользовательских форматов даты и времени Зак 303 0 5 7 Часть II. Библиотека Javaimport java.util.*;class FormatDemo6 {public static void main(String a r g s []) {Formatter fmt = new Formatter();Calendar cal = Calendar.getlnstance();fm t .format("Today is day %te of % cal); System.out.p r intln(fmt); fmt.c l o s e (Вот как выглядит вывод is day 1 of January, 2 Благодаря относительной индексации, аргумент c a l может быть передан только один раз вместо трех. Закры тие объекта класса Обычно объект класса F o r m a t t e r следует закрывать, когда завершаете его использование. Это освобождает все используемые им ресурсы, что особенно важно при форматировании вывода в файл, но ив других случаях это также может быть важно. Приведенные выше примеры демонстрируют один из способов закрыть объект класса F o r m a t t e r — явно вызвать метод c l o s e ( ) . Но начиная с JDK 7 класс F o r m a t t e r реализует интерфейс A u t o C l o s e a b l e . Это значит, что он поддерживает новый оператор t r y -с ресурсами Используя этот подход, можно автоматически закрывать объект класса F o r m a t t e r , когда он больше не нужен. О ператор t r y - с - ресурсами применительно к файлам, описан в главе 13, поскольку файлы — одни из наиболее часто используемых ресурсов, которые следует закрывать. Однако те же фундаментальные методики применяются и здесь. Вот первый пример применения объекта класса F o r m a t t e r , переделанный для автоматического управления ресурсами Использование автоматического управления ресурсами с Formatter, import java.util.*; class FormatDemo { public static void main(String a r g s []) { try (Formatter fmt = new Formatter()) { f m t Форматирование %s просто %d %f", " с Java", Вывод тот же, что и прежде. Подклю чение функции Java printf ( Хотя нет ничего технически неправильного в непосредственном применении класса F o r m a t t e r как это делалось в предыдущих примерах) при создании вы Глава 18. Пакет java.util: прочие служебные классы 5 7 вода для отображения на консоли, существует более удобная альтернатива — метод print f (). Этот метод автоматически использует класс Formatter для создания форматированной строки. Затем он отправляет эту строку в поток System. out, который по умолчанию представляет собой консоль. Метод printf () определен ив классе PrintStream, ив классе Printwriter. Этот метод рассматривается в главе Класс Класс Scanner — это дополнение к классу Formatter. Он читает форматированный вводи преобразует его в бинарную форму. Класс Scanner может применяться для чтения ввода с консоли, из файла, из строки или с другого источника, реализующего интерфейс Readable либо ReadableByteChannel. Например, вы можете использовать класс Scanner для чтения числа с клавиатуры и присвоения его значения переменной. Как вы увидите, несмотря на свою мощь, класс Scanner неожиданно прост в применении. Конструкторы класса S c a n n e Класс Scanner определяет конструкторы, перечисленные в табл. 18.16. В общем случае объект класса Scanner может быть создан для объекта класса String, InputStream, File или любого другого объекта, реализующего интерфейсы Readable либо ReadableByteChannel. Ниже приведены некоторые примеры. Таблица 18.16. Конструкторы класса S c a n n e r Конструктор Описание Scanner(File из throws FileNotFoundException Scanner(File из наборсимволов) throws FileNotFoundException Sca n n e r (InputStream из a nner(InputStream из наборсим волов из throws IOException Scanner(Path из наборсимволов) throws IOException Scanner(Readable из) Создает объект класса Scanner, который использует указанный файл изв качестве входного ис точника Создает объект класса Scanner, который использует указанный файл из с кодировкой, заданной в наборсим волов в качестве входного источника Создает объект класса Scanner, который использует указанный поток изв качестве входного ис точника Создает объект класса Scanner, который использует поток, указанный как из с кодировкой, заданной в наборсим волов, в качестве входного источника Создает объект класса Sanner, который использует файл, определенный параметром из как источник для ввода. (Добавлено в JDK Создает объект класса Sanner, который использует файл, определенный параметром из, с кодировкой символов, определенной параметром наборсимволов, как источник для ввода. Добавлено в JDK Создает объект класса Scanner, который использует указанный параметром из объект интерфейса Readable в качестве входного источника 5 8 Часть II. Библиотека Java К Й Л . j Опмсанце Л ■ ч U Г ‘ , П - - - -Т Создает объект класса Scanner, который исполь- (Readabl еВу t eChanne 1 из ) зует указанный параметром из объект интерфейса в качестве входного источника (Readabl еВу teChanne 1 из, Создает объект класса Scanner, который исполь- S trin g на борсимв о лов) зует указанный параметром из объект интерфейса с кодировкой, заданной параметром наборсим волов, в качестве входного источника (String из) Создает объект класса Scanner, который использует указанную строку в качестве входного источника Следующая последовательность создает объект класса Scanner, который читает файл Test. txt. FileReader fin = new FileReader("Test.txt"); Scanner src = new Это работает, потому что класс FileReader реализует интерфейс Readable. То есть вызов конструктора интерпретируется как Scanner (Следующая строка создает объект класса Scanner, читающий из стандартного ввода, которым по умолчанию является клавиатура conin = new Это работает, потому что объект Sys tern. in — это объект класса Input Stream. То есть вызов конструктора отображается как Scanner (Следующая последовательность создает объект класса Scanner, который читает строку instr = "10 99.88 сканирование очень просто conin = new Основы сканирования После того как вы создаете объект класса Scanner, его очень просто использовать для чтения форматированного ввода. В общем случае объект класса Scanner читает лексемы из некоторого лежащего в основе источника, который вы указываете при создании объекта класса Scanner. Сточки зрения класса Scanner, лексема (token) — это порция ввода, отделенная набором разделителей, которыми по умолчанию являются пробелы. Лексема читается в соответствии с определенным регулярным выражением (regular expression), задающим формат данных. Хотя класс Scanner позволяет определить специфический тип выражения, которому будет соответствовать следующая операция ввода, он включает множество предопределенных шаблонов, соответствующих элементарным типам, таким как int и double, а также строкам. Иными словами, зачастую вы не будете нуждаться в указании шаблонов. В общем случае для использования класса Scanner следуйте описанной ниже процедуре. Определите, доступен ли специфический тип ввода вызовом одного из методов ScannerhasNextX, где X — нужный тип данных. Если ввод доступен, читайте его одним из методов Окончание табл. 18.16
Глава 18. Пакет java.util: прочие служебные классы 5 8 13. Повторяйте процесс до завершения ввода. Закройте объект класса S c a n n e r, вызвав метод c l o s e t ) Как следует из сказанного выше, класс S c a n n e r определяет два набора методов, которые позволяют читать ввод. Первый — это методы h a s N ex t X, перечисленные в табл. 18.17. Эти методы определяют, доступен ли указанный тип ввода. Например, вызов метода h a s N e x t I n t () возвращает значение t r u e только в том случае, если следующая лексема, подлежащая чтению, является целым числом. Если требуемые данные доступны, вычитаете их одним из методов S c a n n e rn e x tX , описанных в табл. 18.18. Например, чтобы прочесть следующее целое число, вызовите метод n e x t I n t (). Приведенная ниже последовательность показывает, как читать список целых чисел, вводимых с клавиатуры conin = new Scanner(System.in); int i ;// Читать список целых while(conin.hasNextlnt()) { i = conin.nextInt(); / Таблица 18.17. Методы h a s N e x t класса S c a n n e rМетодОписаниеboolean h a s N e x t ()boolean hasNext(Pattern шаблон h a s N e x t (String шаблон a s N e x t B i g D e c i m a l () booleanh a s N e x t B i g l n t e g e r ()booleanh a s N e x t B i g l n t e g e r (int основание a s N e x t B o o l e a n () boolean h a s N e x t B y t e (Возвращает значение true, если доступна для чтения следующая лексема любого типа. В противном случае возвращает значение f a l s Возвращает значение true, если доступна для чтения лексема, соответствующая шаблону шаблон В противном случае возвращает значение f a l s e Возвращает значение true, если доступна для чтения лексема, соответствующая шаблону шаблон В противном случае возвращает значение Возвращает значение true, если доступно для чтения значение, которое можно поместить в объект BigDecimal. В противном случае возвращает значение false Возвращает значение true, если доступно для чтения значение, которое можно поместить в объект Biglnteger. В противном случае возвращает значение false. (Поумолчанию используется основание Возвращает значение true, если доступно для чтения значение по основанию основание, которое можно поместить в объект Biglnteger. В противном случае возвращает значение Возвращает значение true, если доступно для чтения значение типа boolean. В противном случае возвращает значение f a l s Возвращает значение true, если доступно для чтения значение типа by te. В противном случае возвращает значение false
5 8 2 Часть II. Библиотека Окончание табл. 18.17МетодОписаниеboolean h a s N e x t B y t e (int основание s N e x t F l o a t ( boolean hasNextInt()boolean h a s N e x t l n t (int основание N e x t L o n g () boolean h a s N e x t L o n g (int long основание e x t S h o r t (int основание Возвращает значение true, если доступно для чтения значение типа byte с указанным основанием основание. В противном случае возвращает значение f a l s Возвращает значение true, если доступно для чтения значение типа double. В противном случае возвращает значение Возвращает значение true, если доступно для чтения значение типа float. В противном случае возвращает значение Возвращает значение true, если доступно для чтения значение, которое можно поместить в объект int. В противном случае возвращает значение f a l s e . (По умолчанию используется основание Возвращает значение true, если доступно для чтения значение типа int с указанным основанием основа ни е. В противном случае возвращает значение Возвращает значение true, если доступна строка ввода Возвращает значение true, если доступно для чтения значение типа long. В противном случае возвращает значение false. (Поумолчанию используется основание Возвращает значение true, если доступно для чтения значение по основанию основан и е. В противном случае возвращает значение Возвращает значение true, если доступно для чтения значение типа short. В противном случае возвращает значение false. (Поумолчанию используется основание Возвращает значение true, если доступно для чтения значение short по основанию основан и е. В противном случае возвращает значение f a l s Таблица 18.18. Методы next класса Scanner Метод "Описание String n e x t (Возвращает следующую лексему любого типа из входного источника Возвращает следующую лексему, соответствующую ша шаблон) блону, переданному в шаблон, из входного источника next(String шаблон) Возвращает следующую лексему, соответствующую шаблону, переданному в шаблон, из входного источника BigDecimal Возвращает следующую лексему как объект e x t B i g D e c i m a l (Возвращает следующую лексему как объект e x t B i g l n t e g e r () Biglnteger. (Поумолчанию используется основание Возвращает следующую лексему как объект e x t B i g l n t e g e r (int основание. Используется основание основание Глава 18. Пакет java.util: прочие служебные классы 8 Окончание табл. 18.18 Метод Описание > boolean n e x t B o o l e a n (Возвращает следующую лексему как значение n e x t B y t e (Возвращает следующую лексему как значение byte. По умолчанию используется основание 10) byte Возвращает следующую лексему как значение типа основание по основанию основание Возвращает следующую лексему как значение типа n e x t F l o a t (Возвращает следующую лексему как значение float int n e x t l n t Возвращает следующую лексему как значение типа int. (Поумолчанию используется основание 10) int nextlnt(int основание Возвращает следующую лексему как значение типа int по основанию основание (Возвращает следующую строку ввода n e x t L o n g (Возвращает следующую лексему как значение типа. (Поумолчанию используется основание 10) long Возвращает следующую лексему как значение типа основание по основанию основание Возвращает следующую лексему как значение типа short. (Поумолчанию используется основание 10) short n e x t S h o r t (Возвращает следующую лексему как значение типа основание по основанию основание В приведенном выше примере цикл while остановится, как только следующая лексема не будет целым числом. То есть цикл прекращает читать целые числа, как только во входном потоке обнаруживается значение, отличное от типа целого числа. Если метод next не может найти тип данных, который он ожидает, передает исключение InputMismatchException. Исключение NoSuchElementExcept ion передается в случае, когда больше нет доступного ввода. Поэтому сначала лучше проверить, что данные требуемого типа доступны, с помощью метода hasNext, прежде чем вызывать соответствующий ему метод Некоторые примеры применения класса S c a n n e Класс Scanner способен существенно упростить ранее утомительную задачу. Давайте рассмотрим несколько примеров. Следующая программа подсчитывает среднее из списка чисел, введенных с клавиатуры Применение Scanner для вычисления среднего из списка значений import java.util.*; class AvgNums { public static void main(String a r g s []) { Scanner conin = new Scanner(System.in); int count = 0; double sum = Введите числа для подсчета среднего Читать и суммировать значения 5 8 Часть II. Библиотека Java while(conin.hasNext()) { if(conin.hasNextDouble()) { sum + = con i n .nextDouble(); count++; } else { String str = conin.n e x t (); готово) break; else Ошибка формата данных Среднее равно " + sum / Эта программа читает числа с клавиатуры, суммирует их в процессе до тех пор, пока пользователь не введет строку " готово. Затем она прекращает вводи отображает среднее значение введенных чисел. Ниже показан пример ее выполнения. Введите числа для подсчета среднего. 1.2 2 3.4 4 готово Среднее равно Программа читает числа до тех пор, пока не получит лексему, которую нельзя интерпретировать как корректное значение типа d o u b le . Когда подобное происходит, она проверяет, что лексема соответствует строке " готово. Если это так, программа завершается нормально. В противном случае она отображает сообщение об ошибке. Обратите внимание на то, что числа читаются с помощью метода n e x t D o u b l e () . Этот метод читает любые числа, которые могут быть преобразованы в тип dou b l e , включая целые значения вроде 2 и значения с плавающей точкой, такие как 3 . 4. То есть число, прочитанное методом n e x t D o u b l e () , не требует наличия десятичной точки. Тот же общий принцип применим к любому методу next. Они найдут соответствие и прочитают данные в любом формате, который может представлять данные запрашиваемого типа. Еще один заслуживающий внимания момент класса S c a n n e r — это то, что одна и та же техника, используемая для чтения одного источника, может быть применена для другого. Например, ниже представлена измененная версия предыдущей программы, предназначенная для чтения списка чисел из файла Использование Scanner для вычисления среднего значения числа из файла
|