Исследование содержание и функциональных особенностей контейнеров или коллекций как классов, хранящих упорядоченные ссылки на ряд объектов. Классы для работы с датой, для генерации случайных чисел, для обеспечения поддержки многих национальных языков.
2. Работа с датами и временем......................................................................................... 2 2.1. Класс Date...............................................................................................................2 2.2. Классы Calendar и GREGORIANCALENDAR...................................................................2 2.3. Класс TIMEZONE...................................................................................................... 6 2.4. Класс SIMPLETIMEZONE .......................................................................................... 8
3. Интерфейс Observer и класс Observable.....................................................................10
4.2. Абстрактные классы используемые при работе с коллекциями...................... 14 4.3. Конкретные классы коллекций............................................................................16 4.4. Класс Collections...................................................................................................22
5. Класс Properties.............................................................................................................23 6. Интерфейс Comparator................................................................................................. 25 7. Класс Arrays...................................................................................................................25 8. Класс STRINGTOKENIZER.................................................................................................... 26 9. Класс BITSET....................................................................................................................26 10. Класс Random..............................................................................................................27
11. Локализация.................................................................................................................28 11.1. Класс Locale........................................................................................................28 11.2. Класс RESOURCEBUNDLE........................................................................................30
2. Работа с датами и временем.........................................................................................2 2.1. Класс Date.....................................................................................................................2 2.2. Классы Calendar и GREGORIANCALENDAR.........................................................................2 2.3. Класс TIMEZONE............................................................................................................ 6 2.4. Класс SIMPLETIMEZONE ................................................................................................ 8
3. Интерфейс Observer и класс Observable....................................................................10
4.2. Абстрактные классы используемые при работе с коллекциями............................14 4.3. Конкретные классы коллекций..................................................................................16 4.4. Класс Collections.........................................................................................................22
5. Класс Properties............................................................................................................ 23
7. Класс Arrays.................................................................................................................. 25
8. Класс STRINGTOKENIZER....................................................................................................26
9. Класс BITSET...................................................................................................................26
10. Класс Random.............................................................................................................27
11. Локализация................................................................................................................28 11.1. Класс Locale..............................................................................................................28 11.2. Класс RESOURCEBUNDLE..............................................................................................30
В Java имеется большое количество вспомогательных классов. Далее мы рассмотрим наиболее важные классы пакета java.util.
2. Работа с датами и временем 2.1. Класс Date
Класс Date изначально предоставлял набор функций для работы с датой - для получения текущего года, месяца и т.д. однако сейчас все эти методы не рекомендованы к использованию и практически всю функциональность для этого предоставляет класс Calendar. Класс Date так же определен в пакете java.sql поэтому желательно указывать полностью квалифицированное имя класса Date.
Существует несколько конструкторов класса Date однако рекомендовано к использованию два
Date() и Date(long date) второй конструктор использует в качестве параметра значение типа long который указывает на количество миллисекунд прошедшее с 1 Января 1970, 00:00:00 по Гринвичу. Первый конструктор создает дату использует текущее время и дату (т.е. время выполнения конструктора). Фактически это эквивалентно второму варианту new Date(System.current-TIMEMILLIS); Можно уже после создания экземпляра класса Date использовать метод SETTIME(long time), для того, что бы задать текущее время.
Для сравнения дат служат методы after(Date date), before(Date date) которые возвращают булевское значение в зависимости от того выполнено условие или нет. Метод COMPARETO(Date ANOTHERDATE) возвращает значение типа int которое равно -1 если дата меньше сравниваемой, 1 если больше и 0 если даты равны. Метод TOSTRING()представляет строковое представление даты, однако для форматирования даты в виде строк рекомендуется пользоваться классом SIMPLEDATEFORMAT определенном в пакте java.text
2.2. Классы Calendar и GREGORIANCALENDAR
Более развитые средства для работы с датами представляет класс Calendar. Calendar является абстрактным классом. Для различных платформ реализуются конкретные подклассы календаря. На данный момент существует реализация Грегорианского календаря - GREGORIANCALENDAR. Экземпляр этого класса получается вызовом статического метода GETINSTANCE(), который возвращает экземпляр класса Gregorian. Подклассы класса Calendar должны интерпретировать объект Dateпо разному. В будущем предполагается реализовать так же лунный календарь, используемый в некоторых странах.
Calendar обеспечивает набор методов позволяющих манипулировать различными "частями" даты, т.е. получать и устанавливать дни, месяцы, недели и т.д.
Программирование на Java
Rendered by www.RENDERX.com
Классы Calendar и GREGORIANCALENDAR Стр. 3 из 42
Если при задании параметров календаря упущены некоторые параметры, то для них будут использованы значения по умолчанию для начала отсчета. т.е.
YEAR = 1970, MONTH = JANUARY, DATE = 1 и т.д.
Для считывания, установки манипуляции различных "частей" даты используются методы get(int filed), set(int filed, int value), add(int field, int amount), roll(int field, inr amount), переменная типа int с именем filed указывает на номер поля с которым нужно произвести операцию. Для удобства все эти поля определены в Calendar, как статические константы типа int.
Рассмотрим подробнее порядок выполнения перечисленных методов. set(int field,int value)
Как уже отмечалось ранее данный метод производит установку какого - либо поля даты. На самом деле после вызова этого метода, немедленного пересчета даты не производится. Пересчет даты будет осуществлен только после вызова методов get(), GETTIME() или TIMEINMILLIS(). Т.о. последовательная установка нескольких полей, не вызовет не нужных вычислений. Помимо этого появляется еще один интересный эффект. Рассмотрим следующий пример. Предположим, что дата установлена на последний день августа. Необходимо перевести ее на последний день сентября. Если внутреннее представление даты изменялось бы после вызова метода set, то при последовательной установке полей мы получили бы вот такой эффект.
public class Test { public Test() { } public static void main(String[] args) {
SIMPLEDATEFORMAT sdf = new SIMPLEDATEFORMAT("yyyy MMMM dd HH:mm:ss"); Calendar cal = Calendar.GETINSTANCE();
cal.set(Calendar.YEAR,2002); cal.set(Calendar.MONTH,Calendar.AUGUST); cal.set(Calendar.DAY_OF_MONTH,31); System.out.println(" Initialy set date: " sdf.format(cal.GETTIME())); cal.set(Calendar.MONTH,Calendar.SEPTEMBER); System.out.println(" Date with month changed : " sdf.format(cal.GETTIME())); cal.set(Calendar.DAY_OF_MONTH,30); System.out.println(" Date with day changed : " sdf.format(cal.GETTIME()));
} }
Initialy set date: 2002 August 31 22:57:47 Date with month changed : 2002 October 01 22:57:47 Date with day changed : 2002 October 30 22:57:47
Программирование на Java
Rendered by www.RENDERX.com
Стр. 4 из 42 Работа с датами и временем
Как видно, в данном примере, при изменении месяца день месяца остался неизменным и было унаследовано его предыдущее значение. Но т.к. в сентябре 30 дней, то дата автоматически была переведена на 1 октября, и, когда было установлено 30 число, то оно относилось бы уже к октябрю месяцу. В следующем примере считывание даты не производится, соответственно ее вычисление не производится, до тех пор пока все поля не установлены.
public class Test { public Test() { } public static void main(String[] args) {
SIMPLEDATEFORMAT sdf = new SIMPLEDATEFORMAT("yyyy MMMM dd HH:mm:ss"); Calendar cal = Calendar.GETINSTANCE();
System.out.println(" Date with day and month changed : " sdf.format(cal.GETTIME()));
} }
Initialy set date: Date with day and month changed : 2002 August 31 23:03:51
2002 September 30 23:03:51
add(int field,int delta)
Добавляет некоторое смещение к существующей величине поля. В принципе то же самое можно сделать с помощью set(f, get(f) delta)
В случае использования метода add следует помнить о двух правилах.
1. Если величина поля изменения выходит за диапазон возможных значений данного поля, то производится деление по модулю данной величины, частное суммируется со следующим по старшинству полем.
2. Если изменяется одно из полей, при этом после изменения младшее по отношению к изменяемому полю, принимает некорректное значение, то оно изменяется, на, которое максимально близко к "старому".
public class Test { public Test() { }
Программирование на Java
Rendered by www.RENDERX.com
Классы Calendar и GREGORIANCALENDAR Стр. 5 из 42 public static void main(String[] args) {
SIMPLEDATEFORMAT sdf = new SIMPLEDATEFORMAT("yyyy MMMM dd HH:mm:ss"); Calendar cal = Calendar.GETINSTANCE();
Current date: 2002 August 31 19:30:00 Rule 1: 2002 August 31 19:31:15
Rule 2: 2002 September 30 19:31:15 roll(int field,int delta)
Добавляет некоторое смещение к существующей величине поля и не производит изменения старших полей. Рассмотрим приведенный ранее пример, но с использованием метода roll public class Test { public Test() { } public static void main(String[] args) {
SIMPLEDATEFORMAT sdf = new SIMPLEDATEFORMAT("yyyy MMMM dd HH:mm:ss"); Calendar cal = Calendar.GETINSTANCE();
Rule 1: 2002 August 31 19:30:15 Rule 2: 2002 September 30 19:30:15
Как видно из результатов работы приведенного выше кода, действие правила 1 изменилось, по сравнению с методом add, а правило 2 действует так же.
2.3. Класс TIMEZONE
Класс TIMEZONE предназначен для совместного использования с классами Calendar и DATEFORMAT. Класс абстрактный, поэтому нельзя создать конкретный экземпляр этого с помощью конструктора. Для этого определен статический метод GETDEFAULT(), который возвращает экземпляр класса TIMEZONEC настройками взятыми из настроек операционной системы под управлением которой работает JVM. Для того, что бы получить экземпляр TIMEZONE с конкретными настройками, можно воспользоваться статическим методом GETTIMEZONE(String ID), в качестве параметра, которому передается наименование конкретного временного пояса, для которого необходимо получить объект TIMEZONE. Нигде не определено публичного набора полей определяющих возможный набор параметров для GETTIMEZONE. Вместо этого определен статический метод String[] GETAVAILABLEIDS() который возвращает массив строк с возможными параметрами для GETTIMEZONE. Можно так определить набор возможных параметров для конкретного временного пояса (рассчитывается относительно Гринвича) String[] GETAVAILABLEIDS(int offset);
Рассмотрим пример в котором на консоль последовательно выводятся
• временная зона по умолчанию
• список всех возможных временных зон
• список временных зон которые совпадают с текущей временной зоной.
Следует обратить внимание что на консоль выводится полное наименование временной зоны. Именно в таком формате следует передавать параметр для GETTIMEZONE(). Хотя и допускается указание строки, которую возвращает метод GETDISPLAYNAME(), так же возможно указание временного пояса в формате "GMT-8:00".
public class Test { public Test() { } public static void main(String[] args) { Test test = new Test();
TIMEZONE tz = TIMEZONE.GETDEFAULT(); int RAWOFFSET = tz.GETRAWOFFSET();
Arabia Standard TIMEASIA/Baghdad Arabia Standard TIMEASIA/Bahrain Arabia Standard TIMEASIA/Kuwait
Arabia Standard TIMEASIA/Qatar raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3)
Программирование на Java
Rendered by www.RENDERX.com
Стр. 8 из 42
Arabia Standard TIMEASIA/Riyadh Eastern African TIMEEAT
Moscow Standard TIMEEUROPE/Moscow Eastern African TIMEINDIAN/Antananar Eastern African TIMEINDIAN/Comoro
Eastern African TIMEINDIAN/Mayotte
Работа с датами и временем raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3) raw offset=10800000;hour offset=(3)
2.4. Класс SIMPLETIMEZONE
Класс SIMPLETIMEZONE являясь потомком TIMEZONE реализует его абстрактные методы и предназначен для использования в настройках использующих Григорианский календарь. В большинстве случаев нет необходимости создавать экземпляр этого класса с помощью конструктора. Вместо этого лучше использовать статические методы которые возвращают экземпляр класса TIMEZONE рассмотренные в предыдущем параграфе. Единственная, пожалуй, причина для использования конструктора - необходимость задания нестандартных правил перехода на зимнее и летнее время.
В классе SIMPLETIMEZONE определено три конструктора. Рассмотрим наиболее полный, с точки зрения функциональности) вариант, который помимо временной зоны задает летнее и зимнее время.
public SIMPLETIMEZONE(int RAWOFFSET, String ID, int STARTMONTH, int STARTDAY, int STARTDAYOFWEEK, int STARTTIME, int ENDMONTH, int ENDDAY, int ENDDAYOFWEEK, int ENDTIME)
RAWOFFSET - временное смещение относительно гринвича
ID - идентификатор временной зоны. (см. пред.параграф)
STARTMONTH - месяц перехода на летнее время
STARTDAY - день месяца перехода на летнее время*
STARTDAYOFWEEK - день недели перехода на летнее время*
STARTTIME - время перехода на летнее время (указывается в миллисекундах) ENDMONTH - месяц окончания действия летнего времени
ENDDAY - день окончания действия летнего времени*
ENDDAYOFWEEK - день недели окончания действия летнего времени* ENDTIME - время окончания действия летнего времени (указывается в миллисекундах)
Месяц перехода времени начинает отсчитываться с нуля. Для этих целей можно применять константы определенные в классе Calendar, например Calendar.JANUARY
Программирование на Java
Rendered by www.RENDERX.com
Класс SIMPLETIMEZONE Стр. 9 из 42
Перевод часов на зимний и летний вариант исчисления времени определяется специальным правительственным указом. Обычно переход на летнее время происходит в 2 часа в последнее воскресенье марта, а переход на зимнее время - в 3 часа в последнее воскресенье октября.
Алгоритм расчета таков
• если STARTDAY 1 и установлен день недели, то будет вычисляться первый день недели STARTDAYOFWEEK месяца STARTMONTH ( например первое воскресенье)
• если STARTDAY -1, и установлен день недели, то будет вычисляться последний день недели STARTDAYOFWEEK месяца STARTMONTH (например последнее воскресенье)
• если день недели STARTDAYOFWEEK установлен в 0, то будет вычисляться число STARTDAY конкретного месяца STARTMONTH
• для того что бы установить день недели после конкретного числа специфицируется отрицательное значение дня недели. Например, что бы указать первый понедельник после 23 февраля используется вот такой набор STARTDAYOFWEEK=-MONDAY, STARTMONTH=FEBRUARY, STARTDAY=23
• для того что бы указать последний день недели перед каким-либо числом, указывается отрицательное значение этого числа и отрицательное значение дня недели. Например, для того что бы указать последнюю субботу перед 23 февраля необходимо задать такой набор параметров STARTDAYOFWEEK=- -SATURDAY, STARTMONTH=FEBRUARY, STARTDAY=-23
• все вышеперечисленное относится так же и к окончанию действия летнего времени.
Рассмотрим пример получения текущей временной зоны с заданием перехода на зимнее и летнее время для России по умолчанию.
public class Test { public Test() { } public static void main(String[] args) { Test test = new Test();
SIMPLETIMEZONE stz = new SIMPLETIMEZONE( TIMEZONE.GETDEFAULT().GETRAWOFFSET()
,TIMEZONE.GETDEFAULT().GETID() ,Calendar.MARCH
,-1 ,Calendar.SUNDAY
,test.GETTIME(2,0,0,0) ,Calendar.OCTOBER
,-1 ,Calendar.SUNDAY
,test.GETTIME(trial,0) );
System.out.println(stz.TOSTRING()); } int GETTIME(int hour,int min,int sec,int ms){ return hour * 3600000 min * 60000 sec * 1000 ms;
Программирование на Java
Rendered by www.RENDERX.com
Стр. 10 из 42 Интерфейс Observer и класс Observable
• Для работы с датой и временем должны использоваться классы Date , Calendar. Класс Calendar абстрактный, существует конкретная реализация этого класса GREGORIANCALENDAR.
• Класс Observer и интерфейс Observable реализуют парадигму MVC и предназначены для уведомления одного объекта об изменении состояния другого.
• Коллекции (Collections) не накладывают ограничений на порядок следования и дублирование элементов.
• Списки (List) поддерживают порядок элементов. (управляется либо самими данными, либо внешними алгоритмами
• Наборы (Set) не допускают дублированных элементов.
• Карты (Maps) используют уникальные ключи, для поиска содержимого.
• Использование массивов делает добавление, удаление и увеличение количества элементов затруднительным.
• Использование связанных (LINKEDLIST) облегчает вставку, удаление и увеличение размера хранилища, но снижает скорость индексированного доступа
• Использование деревьев (Tree) облегчает вставку, удаление и увеличение размера хранилища, снижает скорость индексированного доступа, но увеличивает скорость поиска.
• Использование хэширования облегчает вставку, удаление и увеличение размера хранилища, снижает скорость индексированного доступа, но увеличивает скорость поиска. Однако хэширование требует наличия уникальных ключей для для зпоминания элементов данных
• Класс Properties удобен для хранения наборов параметров в виде пар ключ/значение. Параметры могут сохраняться в потоки (файлы) и загружаться из них.
Программирование на Java
Rendered by www.RENDERX.com
Стр. 38 из 42 Контрольные вопросы
• Реализация классом интерфейса Comparator позволяет сравнивать экземпляры класса друг с другом и, соответственно, сортировать их, например в коллекциях.
• Arrays является классом-утилитой и обеспечивает набор методов, реализующих различные приемы работы с массивами. Не имеет конструктора.
• STRINGTOKENIZER - вспомогательный класс, предназначенный для разбора строк на лексемы.
• При необходимости работать с сущностями, представленными в виде битовых последовательностей, удобно использовать класс BITSET
• Манипуляцию ресурсов, различающихся в зависимости от локализации, удобно осуществлять с помощью классов RESOURCEBUNDLE, LISTRESOURCEBUNDLE, PROPERTIESRESOURCEBUNDLE. Собственно локаль задается с помощью класса Locale.
13. Контрольные вопросы
14-1. Необходимо написать метод, который возвращает случайное число в диапазоне от 0 до 100 кратное 5. Из перечисленных вариантов выберите правильный. a.) public int GETRANDOM5(){ return (int)(Math.random()*20) * 5; }
b.) public int GETRANDOM5(){ Math m = new Math() return (int)(m.random()*20) * 5; }
c.) public int GETRANDOM5(){ return (Math.random()*20) * 5; }
Правильный ответ a. Ответ b неверен т.к. производится попытка создать экземпляр класса Math, что вызовет ошибку компиляции т.к. Math не имеет конструктора. Ответ c не верен, потому что Math.random() возвращает случайную величину типа double в диапазоне от 0.0 до 1.0. Соответственно все выражение будет иметь тип double, а возвращаемое значение у функции типа int, следовательно, возникнет ошибка времени компиляции.
14-2. Какое из выражений относительно класса java.lang.Runtime является корректным? a.) Объект Runtime создается при помощи следующего кода
Runtime r = Runtime.GETRUNTIME();
b.) Метод gc() определенный в Runtime() вызывает начало сборки мусора виртуальной машиной Java
Программирование на Java
Rendered by www.RENDERX.com
Стр. 39 из 42 c.) Метод FREEMEMORY() определенный в классе Runtime, освобождает не используемую память.
Правильный ответ a. Ответ b неверен т.к. процедура запуска сборки мусора запускается самой виртуальной машиной, gc() только уведомляет JVM о необходимости эту процедуру начать. Ответ c неверен, т.к. FREEMEMORY возвращает количество свободной памяти, доступной JVM.
14-3. Необходимо написать метод, который получает в качестве параметра значение угла в градусах типа double и вычисляет его косинус. Какой из приведенных вариантов правилен. a.) double GETCOS(double angle){ return Math.cos(angle);
Правильный ответ b. Ответ a неверен т.к. тригонометрические функции получают в качестве параметра значение угла выраженное в радианах, а не в градусах. Ответ c неверен т.к. константа PI определена в классе Math.
14-4. В JDK 1.2 введены новые классы и интерфейсы, которые позволяют работать с наборами объектов. Отметьте те из них, которые являются интерфейсами. a.) a java.util.List b.) java.util.TREEMAP c.) java.util.ABSTRACTLIST d.) java.util.SORTEDMAP e.) java.util.Iterator f.) java.util.Collections
Правильные ответы a, d, e. TREEMAP является конкретным классом, ABSTRACTLIST абстрактный класс, Collections класс-утилита.
14-5. Какие высказывания относительно java.util.Vector и java.util.Hashtable можно считать корректными a.) В Vector могут сохранятся ссылки как на объекты так и на примитивные типы. b.) Ссылки на объекты в Vector хранятся в порядке их добавления.
Программирование на Java
Rendered by www.RENDERX.com
Стр. 40 из 42 Контрольные вопросы c.) В качестве ключей для Hashtable должны передаваться оъекты типа String d.) Ссылки на объекты в Hashtable хранятся в порядке их добавления. e.) И Hashtable и Vector являются синхронизированными, для того что бы избежать проблема, когда несколько потоков пытаются получить доступ к одной и той же коллекции.
Правильные ответы b, e. Ответ a неверен т.к. в классе Vector могут храниться лишь ссылки на объекты. Для манипулирования примитивными типами используются соответствующие классы-обертки. Ответ c неверен, т.к. в качестве ключа, в Hashtable может использоваться любой объект не только строки. Ответ d неверен, т.к. порядок следования объектов в Hashtable непредсказуем.
14-6. Приведенный ниже пример кода вызывает ошибку компиляции. double GETCOS(double angle){ return Math.cos(angle);
} public static void SHOWSTATUS(Boolean flag){ if(flag){
System.out.println(“FIRED”) }else{
System.out.println(“NOT READY”); }
}
Какое из перечисленных ниже исправлений решит проблему? a.) Заменить if(flag){ на if(flag.equals(true) b.) Заменить public static void SHOWSTATUS(Boolean flag){ на public static void SHOWSTATUS(boolean flag){ c.) Заменить if(flag){ на if(flag.BOOLEANVALUE()){
Правильные ответы b, c. Ответ a неверен т.к. equals метод требует в качестве параметра ссылку на объект, а true есть примитивный тип Boolean.
14-7. Какое значение будет выведено на консоль в существующем фрагменте кода?
String str1 = "abc"; String str2 = "abc";
System.out.println(str1 == str2);
a.) true a.) false
Правильный ответ a. Т.к. строковые литералы, которыми инициализируются строки str1 и str2 одинаковы, то ссылаться они будут на один и тот же объект.
Программирование на Java
Rendered by www.RENDERX.com
Стр. 41 из 42
14-8. Будет ли переменная sb после выполнения кода в строке 2 указывать на тот же самый объект?
1. STRINGBUFFER sb = new STRINGBUFFER("abc"); 2. sb.append("x");
a.) Да b.) Нет
Правильный ответ a. Новый объект создается лишь при манипуляциях с объектом класса String.
14-9. Какой из перечисленных ниже классов имеет набольшее сходство с классом Vector? a.) TREESET. b.) ABSTRACTCOLLECTION. c.) c ARRAYLIST d.) d Hashtable
Правильный ответ c т.к. именно ARRAYLIST наиболее схож по функциональности с Vector. Ответ a неверен т.к. TREESET использует сортировку. Ответ b неверен, т.к. ABSTRACTCOLLECTION абстрактный класс. Ответ d неверен, т.к. Hashtable использует для хранения пары ключ/значение.
14-10. Какой из перечисленный ниже интерфейсов реализует Hashtable? a.) a SORTEDMAP b.) b Map c.) c List d.) d SORTEDSET e.) e ни один из перечисленных
Правильный ответ b. Ответы a, c, d не верны, т.к. Hashtable не реализует эти интерфейсы. Ответ e не верен, т.к. в JDK 1.2 Hashtable переделан и реализует интерфейс Map.