Post on 22-Sep-2020
1
API. Основные классы
2
Пакет java.lang
● Не нужно импортировать — неявный import
● классы:● Object
● Number, Integer, Byte, Short, Long, Double, Float, Boolean, Char
● Math, BigInteger, BigDecimal
● String, StringBuffer, StringBuilder
● System, Runtime, ClassLoader, SecurityManager
● Class, Enum
● Throwable, Exception, Error, RuntimeException
● Thread, ThreadGroup
● интерфейсы● Cloneable
● Runnable
3
Класс Object
● базовый класс иерархии классов Java
● предок всех классов (и массивов)
● неявное расширение
class A extends Object {
}
4
Класс Object
● методы класса Object:● не переопределяемые
◊ final Class<?> getClass()◊ final void wait()◊ final void notify()◊ final void notifyAll()
● переопределяемые
◊ boolean equals()◊ int hashCode()◊ String toString()◊ protected Object clone()◊ protected void finalize()
5
Метод equals
● boolean equals(Object obj)
● obj1 == obj2 — true, если ссылка на один и тот же объект
● obj1.equals(obj2) — эквивалентность значений
● рефлексивность: x.equals(x) == true
● симметрия: x.equals(y) == y.equals(x)
● транзитивность: x.equals(y) == true && y.equals(z) == true, → x.equals(z) == true
● постоянство
● если x != null, то x.equals(null) == false
● при переопределении — сравнение всех значащих полей
6
Метод hashCode()
● int hashCode()
● если объект не модифицировался, то hashCode не должен меняться
● если x.equals(y) == true, то x.hashCode() == y.hashCode()
● если два объекта не эквивалентны, то hashCode не обязан быть разным — коллизия
● по умолчанию обычно возвращает адрес объекта
● при переопределении — скорость, минимизация коллизий
7
Метод toString()
● String toString()
● Возвращает текстовое представление объекта
● Неявно вызывается при конкатенации строки и объекта
"Hello" + obj
"Hello" + obj.toString()
● Для Object — возвращает ClassName@hashСode16
8
Метод clone()
● protected Object clone()
● Возвращаемый объект следует получать с помощью вызова super.clone()
● Класс должен реализовывать интерфейс Cloneable (интерфейс-метка)
● Object не реализует Cloneable
● Object.clone() создает "мелкую" копию — копируются только значения полей
9
Метод finalize()
● protected void finalize()
● Вызывается сборщиком мусора перед удалением объекта
● Предназначен для освобождения системных ресурсов
● Метод Object.finalize() ничего не делает
10
Классы оболочки
● Коллекции не могут содержать примитивные элементы
● Оболочка — представление в виде объекта
● abstract class Number
● Byte, Short, Integer, Long, Float, Double: extends Number
● Character
● Boolean
● Void — объектное представление типа void
11
Number
● Абстрактный класс
● Методы● byte byteValue()
● short shortValue()
● int intValue()
● long longValue()
● float floatValue()
● double doubleValue()
● Потомки — Byte, Short, Integer, Long, Float, Double
12
Методы преобразования
● примитив ↔ объект● конструктор Integer(int), static Integer valueOf(int)
● int intValue()
● автоупаковка/автораспаковка
● строка ↔ объект● конструктор Integer(String),static Integer valueOf(String)
● String toString()
● строка ↔ примитив● static int parseInt(String)
● "" + int
13
Автоупаковка и автораспаковка
● Integer a = Integer.valueOf(5);
● int i = a.intValue();
● Integer a = 5;
● int i = a;
● Integer a = 500; Integer b = 500;● b.equals(a) → true; b == a → false
● Integer c = 10; Integer d = 10;● c.equals(d) → true; c == d → true!
14
Методы сравнения
● interface Comparable<T>● int compareTo(T)
● static int compare(prim, prim)
● boolean equals(Object)
15
Integer, Long::работа с битами
● static int bitCount(int)
● static int highestOneBit(int)
● static int lowestOntBit(int)
● static int numberOfLeadingZeros(int)
● static int numberOfTrailingZeros(int)
● static int reverse(int)
● static int rotateLeft(int, int distance)
● static int rotateRight(int, int distance)
16
Integer, Long :: беззнаковые целые
● compareUnsigned(x, y)
● divideUnsinged(x, y)
● remainderUnsigned(x, y)
● parseUnsignedInt(String) (parseUnsignedLong)
● toUnsignedInt(x) (toUnsignedLong)
● toUnsingedString(x)
17
Boolean
● compareTo● TRUE.compareTo(TRUE) = 0
● FALSE.compareTo(FALSE) = 0
● TRUE.compareTo(FALSE) = +
● FALSE.compareTo(TRUE) = -
● parseBoolean(String), valueOf(String)● true, если строка содержит "true" без учета регистра
● false, если не содержит
18
Character
● char — 16 бит
● Unicode (сначала 16 бит, потом 21)● U+0000 ... U+10FFFF
● U+0000 ... U+FFFF — Basic Multilingual Plane
● UTF-16● \uD800 ... \uDBFF — high surrogate
● \uDC00 ... \uDFFF — low surrogate
● int toCodePoint(char high, char low)
● char[] toChars(int codePoint)
● Методы принимают или char или int:● isDigit, isLetter, isSpaceChar, isLowerCase, isUpperCase, isTitlecase
● toLowerCase, toUpperCase, toTitleCase
● DŽ (upper), Dž (title), dž (lower)
19
String
● Строка — константа
● String s = "Hello";
s = s.replace('e', 'u') — создается новый объект
● Компилятор сохраняет строки в пул
● "Hello, " + "world" == "Hello, world"
● метод intern() помещает строку в пул, если ее там нет
20
Конструкторы String
● String()
● String(byte[])
● String(byte[], int offset, int count)
● String(char[])
● String(char[], int offset, int count)
● String(int[], int offset, int count)
● String(String)
● String(StringBuilder)
● String(StringBuffer)
21
Методы String
● int length()
● char charAt()
● int codePointAt()
● String concat(String)
● String substring(int begin, int end)
● int indexOf
● int lastIndexOf
● boolean compareTo()
● String replace()
● String trim()
● static String valueOf()
22
StringBuilder и StringBuffer
● StringBuffer — потокобезопасный
● StringBuilder — быстрый
● Конструкторы● StringBuilder()
● StringBuilder(String)
● Методы● String toString()
● append(x) — используется при операции + со строками
● insert(int, x)
● deleteCharAt()
● setCharAt()
● replace
23
Math
● Константы PI, E
● математические функции
24
System
● System.in, System.out, System.err — стандартные потоки
● Console console()● printf(), format()
● readLine(), readPassword()
● exit(int status)● 0 — удачное завершение
● getenv()
● getProperties()
● getSecurityManager()● checkXXX()
● long currentTimeMillis()● nanoTime()
25
Обработка исключения
● Правило "Catch or Specify"
try {
m();
} catch (MyException e) {
System.out.println("А-а-а! Мы все умрём!");
System.exit(666);
} catch (Exception e) {
System.out.println("Или не все...");
} finally {
// закрыть ресурсы
}
26
finally выполняется всегда!
public int test() {
try {
return 0;
} finally {
return 1;
}
}
System.out.println(test());
27
try с ресурсами
● ресурс должен реализовывать интерфейс AutoCloseable
try (Scanner s = new Scanner(System.in)) {
...
} catch (IOException e) {
}
● при выходе из блока try будет вызван метод close()
28
Коллекции
29
Коллекции
● Коллекции предназначены для группировки объектов
● Коллекции могут хранить только ссылочные типы
● Коллекции используют обобщенные типы данных
30
Обобщенные и параметризованные типы
● Stack a = new Stack();
a.put("Hello"); // void put(Object)
String s = (String) a.get(); // Object get()
● Stack<String> b = new Stack<String>(); // Stack<>()
b.put("Hello");
String s = b.get();
● class Stack<T> {
private T object;
void put(T t) { object = t; }
T get() { return object; }
}
31
Ограничение параметров типа
● class NumberStack<T extends Number> {
public int intValue() {
return T.intValue();
}
}
32
Приведение типов и шаблоны
● Number n = new Integer(10);
● Stack<Number> s = new Stack<Integer>(); // error
Stack<Integer> не потомок Stack<Number>
● Stack<?> s = new Stack<Integer>();
● Stack<? extends Number> s = new Stack<Integer>();
33
Стирание типов
● На уровне виртуальной машины обобщенные типы отсутствуют — заменяются на "сырые"
● Добавляется приведение типов
● Совместимость с предыдущими версиями
● Потенциальная возможность несовпадения типов
34
Интерфейс java.util.Collection<E>
● int size()
● boolean isEmpty()
● boolean contains(Object)
● booelan add(E) // true если коллекция изменилась
● boolean remove(Object) // true если коллекция изменилась
● Iterator<E> iterator()
● void clear()
● containsAll(), addAll(), removeAll(), retainAll()
● for (E e : collection) { e }
● for (Iterator i = collection.iterator(); i.hasNext(); ) { i.next(); }
35
Интерфейс Set<E>
● Множество (нет повторяющихся элементов)
● s.containsAll(t) - true, если t — подмножество s
● s.addAll(t) — объединение s и t
● s.retainAll(t) — пересечение s и t
● s.removeAll(t) — разность s и t
● HashSet — самая быстрая реализация, нет порядка
● TreeSet — медленная реализация, натуральный порядок
● LinkedHashSet — средняя скорость, порядок добавления
● Set<Integer> s = new HashSet<Integer>();
36
Интерфейс List<E>
● Список или последовательность — индексация
● E get(int)
● E set(int, E)
● void add(int, E)
● E remove(int)
● indexOf(Object)
● lastIndexOf(Object)
● listIterator() // hasPrevious(), previous()
● ArrayList — оптимальная реализация
● LinkedList — для большого числа вставок-удалений
37
Интерфейс Queue<E>
● Очередь
● add(E), E remove(), E element() - исключение
● offer(E), E poll(), E peek() - специальное значение
● LinkedList — сортировка FIFO
● PriorotyQueue — сортировка по значению
38
Интерфейс Deque<E>
● Очередь + стек
● addFirst/Last(E), E removeFist/Last(), E getFirst/Last()
● offerFirst/Last(E), E pollFirst/Last(), E peekFirst/Last()
● ArrayDeque
● LinkedList
39
Интерфейс Map<K,V>
● Хранит пары ключ-значение
● V put(K,V)
● V get(K)
● V remove(K)
● boolean containsKey(K)
● boolean containsValue(V)
● int size()
● boolean isEmpty()
● Set keySet()
● Set entrySet()
● Collection values()
● HashMap
● TreeMap
● LinkedHashMap
40
класс Collections
● статические методы, возвращающие:● синхронизированные коллекции synchronizedCollection()
● немодифицируемые коллекции unmodifiableCollection()
● проверяемые коллекции checkedCollection()
● алгоритмы● sort()
● shuffle()
● reverse()
● fill()
● swap()
● binarySearch()
41
Сортировка (отдельный компаратор)
public class A {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
list.sort(new C());
for (String s : list) { System.out.println(s); }
}
}
class C implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
42
Сортировка (статический вложенный класс)
public class A {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
list.sort(new C());
for (String s : list) { System.out.println(s); }
}
static class C implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
}
43
Сортировка (внутренний класс)
public class A {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
list.sort(new A().new C());
for (String s : list) { System.out.println(s); }
}
class C implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
}
44
Сортировка (локальный класс)
public class A {
public static void main(String[] args) {
class C implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
List<String> list = Arrays.asList(args);
list.sort(new C());
for (String s : list) { System.out.println(s); }
}
}
45
Сортировка (анонимный класс)
public class A {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
list.sort(new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
for (String s : list) { System.out.println(s); }
}
}
46
Сортировка (лямбда-выражение)
public class A {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
list.sort(
(String s1, String s2) -> s1.length() - s2.length()
);
for (String s : list) { System.out.println(s); }
}
}
● sort(Comparator c)
● @FunctionalInterface interface Comparator
● int compare(T o1, T o2);
47
Сортировка и вывод списка (лямбда)
public class A {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
list.sort(
(String s1, String s2) -> s1.length() - s2.length()
);
list.forEach((s) -> System.out.println(s));
}
}
48
Сортировка и вывод списка (ссылка на метод)
public class A {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
list.sort(
(String s1, String s2) -> s1.length() - s2.length()
);
list.forEach(System.out::println);
}
}
49
Ввод-вывод
50
Пакет java.io
1)Байтовые и символьные потоки данных (I/O streams)● Поток — последовательность данных (байтов, символов,
примитивных типов, объектов)
● Входной поток — для чтения данных из источника
● Выходной поток — для записи данных в приемник
2)Старый интерфейс работы с файлами — класс File
51
Потоки ввода-вывода
● Байтовые и символьные
● Входные и выходные
● Базовые абстрактные классы для потоков
java.io.InputStream java.io.OutputStream
java.io.Writerjava.io.Reader
52
java.io.InputStream
● абстрактный метод int read()● возвращает байт от 0 до 255, если доступен
● если недоступен — блокируется и ждет
● если поток завершился — возвращает -1
● при ошибке — IOException
● реализованные методы:● int read(byte[] buffer, int len, int offset)
● int read(byte[] buffer)
● int available()
● long skip(long n)
● boolean markSupported()
● void mark(int limit)
● void reset()
● void close()
53
java.io.Reader
● абстрактный метод int read(char[] buffer, int len, int offset)● читает символы в массив, возвращает число прочитанных (-1 при завершении)
● если недоступен — блокируется и ждет
● при ошибке — IOException
● abstract void close()
● реализованные методы:● int read()
● int read(char[] buffer)
● boolean ready()
● int available()
● long skip(long n)
● boolean markSupported()
● void mark(int limit)
● void reset()
54
java.io.OutputStream
● абстрактный метод void write(int b)● записывает байт
● при ошибке — IOException
● реализованные методы:● void write(byte[] buffer, int len, int offset)
● void write(byte[] buffer)
● void flush()
● void close()
55
java.io.Writer
● абстрактный метод void write(char[] buffer, int len, int offset)● записывает символы из массива
● при ошибке — IOException
● abstract void flush()
● abstract void close()
● реализованные методы:● void write(byte[] buffer, int len, int offset)
● void write(char[] buffer)
● void write(String str, int len, int offset)
● void write(String str)
● Writer append(char c)
● Writer append(CharSequence cs)
56
Специализированные потоки
● Работают с определенным источником/приемником
● Обычно источник/приемник указывается в конструкторе● чтение/запись файла
◊ File (InputStream, OutputStream, Reader, Writer)
● чтение/запись массива
◊ ByteArray (InputStream, OutputStream)◊ CharArray (Reader, Writer)
● чтение/запись в конвейер (взаимодействие потоков выполнения)
◊ Piped (InputStream, OutputStream, Reader, Writer)◊ соединение потоков в конвейер
● передача парного потока в конструктор● вызов метода connect()
● чтение/запись строк (только символьные потоки)
◊ String (Reader, Writer)
57
Потоки-фильтры
● Filter (InputStream, OutpurStream, Reader, Writer)● принимают исходный поток как аргумент конструктора
● получившийся поток-фильтр преобразует исходный поток
● Buffered (InputStream, OutpurStream, Reader, Writer)
● LineNumber (InputStream, Reader)
● Print (Stream, Writer)
● ZIP (InputStream, OutputStream)
● Data (InputStream, OutpurStream)
● Object (InputStream, OutpurStream)
● байты ↔ символы● InputStreamReader (байты в символы)
● OutputStreamWriter (символы в байты)
58
PrintStream, PrintWriter
● методы print, println — один аргумент примитивного типа, строка или объект
● методы printf, format — много аргументов, первый из которых — форматная строка
● Синтаксис форматной строки● %[индекс$][флаги][размер][.точность]формат
● %% - символ процента
● %n — перевод строки
● индекс — порядковый номер аргумента или < (предыдущий)
● флаги — зависят от формата
● размер — количество символов для представления числа
● точность — цифры после запятой для дробных форматов
● format("%c = %2$+9.7f", 'π', Math.PI);
● π = +3,1415927
59
Нечисловые форматы
● Общие - любой тип аргумента
● Заглавная буква формата - toUpperCase()):
● %b, %B - boolean● boolean, Boolean → значение
● null → false
● все остальное → true
● %h, %H — hashcode● null → null
● все остальное — 16-ричный хэш-код
● %s, %S — строка● Formattable → formatTo()
● все остальное → toString()
● %c, %C — символ Unicode
● %t, %T — префикс для форматов даты/времени
60
Целые числа
● %d — десятичное целое
● %o — 8-ричное целое
● %x, %X — 16-ричное целое
Флаги
● '-' - левое выравнивание
● '#' - для недесятичных чисел — добавить 0 или 0x
● '+' - обязательно использовать знак
● ' ' - пробел на месте знака для положительных
● '0' — использовать ведущие нули
● ',' - использовать групповой разделитель для десятичных
● '(' - отрицательные — в скобках
поле размер — количество цифр в формате
61
Числа с плавающей запятой
● %e, %E — научная нотация с мантиссой и порядком
● %f — десятичная нотация
● %g, %G — научная или десятичная (зависит от точности)
● %a, %A — 16-ричная с мантиссой и порядком
Флаги — такие же, как для целых
Точность — количество цифр после запятой● для %g/G — общее количество значащих цифр и 10точность —
максимальное число, представляемое в десятичной форме (минимальное — 10-4). По умолчанию =6, то есть как десятичные дроби представляются числа от 0,0001 до 999999
62
Scanner
● Конструкторы● Scanner(File)
● Scanner(Path)
● Scanner(InputStream)
● Scanner(Readable)
● Scanner(String)
● Методы● boolean hasNext(), String next()
● Boolean hasNextInt(), int nextInt(),
● ….
● String nextLine()
● void useDelimiter(String)
● void useRadix(int)
63
DataInputStream, DataOutputStream
● Преобразование примитивных типов и строк в последовательность байтов
● Последовательность при чтении должна быть такой же как и при записи
● Методы:● writeBoolean(boolean), writeByte(int), writeShort(int), writeInt(int),
writeLong(long), writeFloat(float), writeDouble(double), writeChar(int), writeUTF(String)
● bolean readBoolean(), byte readByte(), int readUnsignedByte() short readShort(), int readUnsignedShort(), int readInt(), long readLong(), float readFloat(), double readDouble(), char readUTF()
64
Сериализация объектов
● Сериализация — запись объектов в виде потока байтов
● Классы ObjectOutputStream, ObjectInputStream
● Интерфейс Serializable - метка
● При записи объекты записываются с порядковым номером (serial number)
● Объект записывается в поток только один раз, потом используется ссылка на номер объекта
● При чтении одного и того же объекта из одного потока, он восстанавливается один раз
● При чтении объекта из двух потоков, объект восстанавливается дважды
65
ObjectOutputStream, ObjectInputStream
● Те же методы, что и у DataOutputStream, DataInputStream
● + writeObject(Object)
● + Object readObject()
● Методы записывают/читают:● класс объекта
● сигнатуру класса (вычисляется как хэш-функция первых двух элементов дайджеста SHA-1 из имени и модификаторов класса, интерфейсов, типов и имен полей, имен и сигнатур конструкторов и методов)
● сигнатура класса может быть записана в поле serialVersionUID
● значения нестатических и непереходных полей данного класса, и всех его суперклассов
● поля с модификатором transient (переходные) не сериализуются
● поля записываются в поток иерархически
66
Переопределение стандартной сериализации
● Методы в сериализуемом классе● private void writeObject(ObjectOutputStream os)
● private void readObject(ObjectInputStream is)
● в методах вызываются методы класса Object...Stream:
◊ os.defaultWriteObject()◊ is.defaultReadObject()
● методы заботятся только о своих данных (суперкласс не трогаем)
● интерфейс Externalizable● методы (обрабатывают весь объект, включая данные
суперкласса):
◊ writeExternal(ObjectOutput o)◊ readExternal(ObjectInput i)
67
java.nio
● java.nio.Buffer — контейнер для хранения данных
● Создание буфера: allocate(capacity), wrap(array[])
● Методы:● limit(lim) и position(pos)
● mark() и reset() mark <-> position
● clear() - позиция = 0, граница = емкость
● flip() - граница = позиция, позиция = 0
● rewind() - позиция = 0
limit capacitypositionmark
get/put
68
Запись и чтение данных
● методы get и put
● Относительная индексация (по текущей позиции)● позиция смещается после операции
● одиночные и групповые операции
● Абсолютная индексация (явное указание индекса)● позиция не меняется
● только одиночные
● Стандартное использование буфера — заполнение (запись), потом получение данных (чтение)
69
Запись и чтение данных
● clear();
while () {
put(byte);
}
● flip();
while(hasRemaining()) {
get();
}
● rewind();
while(hasRemaining()) {
get();
}
70
Классы-потомки Buffer
● ByteBuffer
● CharBuffer
● IntBuffer, ShortBuffer, LongBuffer, FloatBuffer, DoubleBuffer
71
java.nio.charset
● Класс Charset● методы
● CharBuffer decode(ByteBuffer b)
● ByteBuffer encode(CharBuffer c)
72
Каналы
● java.nio.channels
● Файловые каналы и сетевые каналы
● FileChannel● FileChannel.open(), FileInputStream.getChannel()
● write(ByteBuffer b) — запись в данный канал данных из буфера
● read(ByteBuffer b) — чтение из канала данных в буфер
● write для канала = get для буфера
● read для канала = put для буфера
● map() - получение MappedByteBuffer — отображение файла в память
73
Работа с путями (java.nio.file.*)
● Класс Path — путь к файлу в файловой системе
● Paths — класс-помощник
● Path p1 = Paths.get("/home/s888888");
● Path p2 = Paths.get("C:\\Users\s888888");
● Path p3 =Paths.get("home", "s888888");
● Path p = Paths.get(System.getProperty("user.home"));
74
Работа с файлами: проверки
● Класс Files● booelan Files.exists(Path)
● booelan Files.notExists(Path)
● booelan Files.isReadable(Path)
● booelan Files.isWritable(Path)
● booelan Files.isExecutable(Path)
75
Работа с файлами: создание и удаление
● Path Files.createFile(Path)
● Path Files.createDirectory(Path)
● Path Files.createDirectories(Path)
● Path Files.createTempFile(String prefix, String suffix)
● Path Files.createLink(Path, Path)
● Path Files.createSymbolicLink(Path, Path)
● void Files.delete(Path)
● boolean Files.deleteIfExists(Path)
76
Работа с файлами: копирование и перемещение
● Path Files.copy(Path, Path)
● Path Files.move(Path, Path)
77
Работа с файлами: чтение и запись
● byte[] Files.readAllBytes(Path)
● List<String> Files.readAllLines(Path)
● Path Files.write(Path, byte[])
● Path Files.write(Path, Iterable<CharSequence>)
78
java.lang.reflect
● Класс java.lang.Class
● Получение объекта класса Class● new A().getClass();
● Class.forName("A");
● A.class
● Методы● Field[] getFields()
● Method[] getMethods()
● Constructor[] getConstructors()
● isInterface()
● isArray()
79
Многопоточность
80
Потоки выполнения
● Процесс имеет собственный контекст исполнения, собственный набор ресурсов, свою выделенную память.
● Поток (thread) существует внутри процесса, делит память и ресурсы с другими потоками.
● Потоки в JVM● системные потоки:
◊ основной поток виртуальной машины◊ сборщик мусора◊ поток периодических задач◊ поток динамической компиляции
● прикладные потоки
◊ основной поток (main)◊ создаваемые программным путем
81
Класс Thread и интерфейс Runnable
● public class Thread implements Runnable
● 2 варианта создания потока
1) public class A extends Thread {
public void run() { /* тело потока*/ }
}
new A().start;
2) public class A implements Runnable {
public void run() { /* тело потока */ }
}
new Thread(new A()).start();
82
Приостановка и прерывание потока
● try {
Thread.sleep(1000); // спать 1 с
} catch (InterruptedException e) { }
● try {
t.join(1000); // ожидать завершения t в течение 1 с
} catch (InterruptedException e) { }
● t.interrupt(); // устанавливает флаг прерывания
● if (Thread.interrupted() { // сбрасывает флаг
throw new InterruptedException();
}
83
Множественный доступ к переменным
class A {
int counter = 0;
public void up() { counter++; }
public void down() { counter--; }
}
1) получить значение counter
2) увеличить/уменьшить значение на 1
3) сохранить новое значение
1)00
1)00
2) 10
2)-10
3)-1-1
3)11
действиестек
counter
84
Синхронизация
class A {
int counter = 0;
public synchronized void up() { counter++; }
public synchronized void down() { counter--; }
}
● Любой объект имеет монитор
● Поток может выполнить synchronized метод, только захватив монитор
● При выходе из метода поток освобождает монитор
● Для уменьшения времени захвата монитора используются блоки synchronized
synchronized(Object) { }
85
Модификатор volatile
● Переменные класса — общие для всех потоков
● Потоки могут сохранять значения общих переменных в локальном кэше
● Модификатор volatile указывает, что доступ к этой переменной из потоков должен производиться напрямую
86
Взаимодействие потоков
● Методы wait(), notify(), notifyAll()
● Для вызова этих методов поток должен иметь монитор данного объекта, поэтому они вызываются в синхронизированном блоке или методе.
● wait() - поток помещается в список ожидания и освобождает монитор. После выхода из списка ожидания, он может получить монитор, и завершить метод wait.
● notify() - выводит из списка ожидания один из потоков.
● notifyAll() - выводит из списка ожидания все потоки.
87
Диаграмма работы wait/notify
class A {
boolean flag = false;
int value;
synchronized void put(int i) {
while(flag) { wait(); }
flag = true; value = i;
notifyAll();
}
synchronized int get() {
while(!flag) { wait(); }
flag = false;
notifyAll();
return value;
}
}
start() start()
get() BLOCKED
wait()
WAITING put(5)
start() false 0
false 0
false 0
true 5
notify() true 5WAITING
notify()
WAITING
false 5FINISHED
BLOCKED
return 5
FINISHED
88
Состояния потока
new
run()runnable
terminated
blocked
waiting
timedwaiting
start()
диспетчеризация
sleep(time)
wait()notify()
окончание работы
ожидание монитора synchronized
захват монитора synchronized
89
Проблемы многопоточности
● Взаимная блокировка (deadlock)
● Ресурсное голодание (starvation)
● Зацикливание (livelock)
90
пакет java.util.concurrent
● Исполнители● interface Executor : void execute(Runnable)
● interface ExecutorService : Future submit(Callable)
● interface Callable<V> : V call()
● interface Future<V> : V get()
● interface ScheduledExecutorService : ScheduledFuture schedule()
● Реализации● class ThreadPoolExecutor
● class ScheduledThreadPoolExecutor
● Вспомогательный класс● Executors
◊ создание ExecutorService, ScheduledExecutorService, Callable
91
пакет java.util.concurrent.locks
● интерфейс Lock
Lock l = new ReentrantLock();
l.lock(); // tryLock()
try { /* доступ к защищенному ресурсу */ }
finally { l.unlock(); }
● интерфейс Condition
Condition c = l.newCondition();
l.lock();
try {
while(flag) { c.await(); }
flag = true;
c.signal();
} finally { l.unlock(); }
92
пакет java.util.concurrent.atomic
● Содержит классы для реализации атомарных операций
class A {
AtomicInteger counter = new AtomicInteger(0);
public void up() { counter.incrementAndGet(); }
public void down() { counter.decrementAndGet(); }
}
93
Ввод-вывод
94
Пакет java.io
1)Байтовые и символьные потоки данных (I/O streams)● Поток — последовательность данных (байтов, символов,
примитивных типов, объектов)
● Входной поток — для чтения данных из источника
● Выходной поток — для записи данных в приемник
2)Старый интерфейс работы с файлами — класс File
95
Потоки ввода-вывода
● Байтовые и символьные
● Входные и выходные
● Базовые абстрактные классы для потоков
java.io.InputStream java.io.OutputStream
java.io.Writerjava.io.Reader
96
java.io.InputStream
● абстрактный метод int read()● возвращает байт от 0 до 255, если доступен
● если недоступен — блокируется и ждет
● если поток завершился — возвращает -1
● при ошибке — IOException
● реализованные методы:● int read(byte[] buffer, int len, int offset)
● int read(byte[] buffer)
● int available()
● long skip(long n)
● boolean markSupported()
● void mark(int limit)
● void reset()
● void close()
97
java.io.Reader
● абстрактный метод int read(char[] buffer, int len, int offset)● читает символы в массив, возвращает число прочитанных (-1 при завершении)
● если недоступен — блокируется и ждет
● при ошибке — IOException
● abstract void close()
● реализованные методы:● int read()
● int read(char[] buffer)
● boolean ready()
● int available()
● long skip(long n)
● boolean markSupported()
● void mark(int limit)
● void reset()
98
java.io.OutputStream
● абстрактный метод void write(int b)● записывает байт
● при ошибке — IOException
● реализованные методы:● void write(byte[] buffer, int len, int offset)
● void write(byte[] buffer)
● void flush()
● void close()
99
java.io.Writer
● абстрактный метод void write(char[] buffer, int len, int offset)● записывает символы из массива
● при ошибке — IOException
● abstract void flush()
● abstract void close()
● реализованные методы:● void write(byte[] buffer, int len, int offset)
● void write(char[] buffer)
● void write(String str, int len, int offset)
● void write(String str)
● Writer append(char c)
● Writer append(CharSequence cs)
100
Специализированные потоки
● Работают с определенным источником/приемником
● Обычно источник/приемник указывается в конструкторе● чтение/запись файла
◊ File (InputStream, OutputStream, Reader, Writer)
● чтение/запись массива
◊ ByteArray (InputStream, OutputStream)◊ CharArray (Reader, Writer)
● чтение/запись в конвейер (взаимодействие потоков выполнения)
◊ Piped (InputStream, OutputStream, Reader, Writer)◊ соединение потоков в конвейер
● передача парного потока в конструктор● вызов метода connect()
● чтение/запись строк (только символьные потоки)
◊ String (Reader, Writer)
101
Потоки-фильтры
● Filter (InputStream, OutpurStream, Reader, Writer)● принимают исходный поток как аргумент конструктора
● получившийся поток-фильтр преобразует исходный поток
● Buffered (InputStream, OutpurStream, Reader, Writer)
● LineNumber (InputStream, Reader)
● Print (Stream, Writer)
● ZIP (InputStream, OutputStream)
● Data (InputStream, OutpurStream)
● Object (InputStream, OutpurStream)
● байты ↔ символы● InputStreamReader (байты в символы)
● OutputStreamWriter (символы в байты)
102
PrintStream, PrintWriter
● методы print, println — один аргумент примитивного типа, строка или объект
● методы printf, format — много аргументов, первый из которых — форматная строка
● Синтаксис форматной строки● %[индекс$][флаги][размер][.точность]формат
● %% - символ процента
● %n — перевод строки
● индекс — порядковый номер аргумента или < (предыдущий)
● флаги — зависят от формата
● размер — количество символов для представления числа
● точность — цифры после запятой для дробных форматов
● format("%c = %2$+9.7f", 'π', Math.PI);
● π = +3,1415927
103
Нечисловые форматы
● Общие - любой тип аргумента
● Заглавная буква формата - toUpperCase()):
● %b, %B - boolean● boolean, Boolean → значение
● null → false
● все остальное → true
● %h, %H — hashcode● null → null
● все остальное — 16-ричный хэш-код
● %s, %S — строка● Formattable → formatTo()
● все остальное → toString()
● %c, %C — символ Unicode
● %t, %T — префикс для форматов даты/времени
104
Целые числа
● %d — десятичное целое
● %o — 8-ричное целое
● %x, %X — 16-ричное целое
Флаги
● '-' - левое выравнивание
● '#' - для недесятичных чисел — добавить 0 или 0x
● '+' - обязательно использовать знак
● ' ' - пробел на месте знака для положительных
● '0' — использовать ведущие нули
● ',' - использовать групповой разделитель для десятичных
● '(' - отрицательные — в скобках
поле размер — количество цифр в формате
105
Числа с плавающей запятой
● %e, %E — научная нотация с мантиссой и порядком
● %f — десятичная нотация
● %g, %G — научная или десятичная (зависит от точности)
● %a, %A — 16-ричная с мантиссой и порядком
Флаги — такие же, как для целых
Точность — количество цифр после запятой● для %g/G — общее количество значащих цифр и 10точность —
максимальное число, представляемое в десятичной форме (минимальное — 10-4). По умолчанию =6, то есть как десятичные дроби представляются числа от 0,0001 до 999999
106
Scanner
● Конструкторы● Scanner(File)
● Scanner(Path)
● Scanner(InputStream)
● Scanner(Readable)
● Scanner(String)
● Методы● boolean hasNext(), String next()
● Boolean hasNextInt(), int nextInt(),
● ….
● String nextLine()
● void useDelimiter(String)
● void useRadix(int)
107
DataInputStream, DataOutputStream
● Преобразование примитивных типов и строк в последовательность байтов
● Последовательность при чтении должна быть такой же как и при записи
● Методы:● writeBoolean(boolean), writeByte(int), writeShort(int), writeInt(int),
writeLong(long), writeFloat(float), writeDouble(double), writeChar(int), writeUTF(String)
● bolean readBoolean(), byte readByte(), int readUnsignedByte() short readShort(), int readUnsignedShort(), int readInt(), long readLong(), float readFloat(), double readDouble(), char readUTF()
108
Сериализация объектов
● Сериализация — запись объектов в виде потока байтов
● Классы ObjectOutputStream, ObjectInputStream
● Интерфейс Serializable - метка
● При записи объекты записываются с порядковым номером (serial number)
● Объект записывается в поток только один раз, потом используется ссылка на номер объекта
● При чтении одного и того же объекта из одного потока, он восстанавливается один раз
● При чтении объекта из двух потоков, объект восстанавливается дважды
109
ObjectOutputStream, ObjectInputStream
● Те же методы, что и у DataOutputStream, DataInputStream
● + writeObject(Object)
● + Object readObject()
● Методы записывают/читают:● класс объекта
● сигнатуру класса (вычисляется как хэш-функция первых двух элементов дайджеста SHA-1 из имени и модификаторов класса, интерфейсов, типов и имен полей, имен и сигнатур конструкторов и методов)
● сигнатура класса может быть записана в поле serialVersionUID
● значения нестатических и непереходных полей данного класса, и всех его суперклассов
● поля с модификатором transient (переходные) не сериализуются
● поля записываются в поток иерархически
110
Переопределение стандартной сериализации
● Методы в сериализуемом классе● private void writeObject(ObjectOutputStream os)
● private void readObject(ObjectInputStream is)
● в методах вызываются методы класса Object...Stream:
◊ os.defaultWriteObject()◊ is.defaultReadObject()
● методы заботятся только о своих данных (суперкласс не трогаем)
● интерфейс Externalizable● методы (обрабатывают весь объект, включая данные
суперкласса):
◊ writeExternal(ObjectOutput o)◊ readExternal(ObjectInput i)
111
java.nio
● java.nio.Buffer — контейнер для хранения данных
● Создание буфера: allocate(capacity), wrap(array[])
● Методы:● limit(lim) и position(pos)
● mark() и reset() mark <-> position
● clear() - позиция = 0, граница = емкость
● flip() - граница = позиция, позиция = 0
● rewind() - позиция = 0
limit capacitypositionmark
get/put
112
Запись и чтение данных
● методы get и put
● Относительная индексация (по текущей позиции)● позиция смещается после операции
● одиночные и групповые операции
● Абсолютная индексация (явное указание индекса)● позиция не меняется
● только одиночные
● Стандартное использование буфера — заполнение (запись), потом получение данных (чтение)
113
Запись и чтение данных
● clear();
while () {
put(byte);
}
● flip();
while(hasRemaining()) {
get();
}
● rewind();
while(hasRemaining()) {
get();
}
114
Классы-потомки Buffer
● ByteBuffer
● CharBuffer
● IntBuffer, ShortBuffer, LongBuffer, FloatBuffer, DoubleBuffer
115
java.nio.charset
● Класс Charset● методы
● CharBuffer decode(ByteBuffer b)
● ByteBuffer encode(CharBuffer c)
116
Каналы
● java.nio.channels
● Файловые каналы и сетевые каналы
● FileChannel● FileChannel.open(), FileInputStream.getChannel()
● write(ByteBuffer b) — запись в данный канал данных из буфера
● read(ByteBuffer b) — чтение из канала данных в буфер
● write для канала = get для буфера
● read для канала = put для буфера
● map() - получение MappedByteBuffer — отображение файла в память
117
Работа с путями (java.nio.file.*)
● Класс Path — путь к файлу в файловой системе
● Paths — класс-помощник
● Path p1 = Paths.get("/home/s888888");
● Path p2 = Paths.get("C:\\Users\s888888");
● Path p3 =Paths.get("home", "s888888");
● Path p = Paths.get(System.getProperty("user.home"));
118
Работа с файлами: проверки
● Класс Files● booelan Files.exists(Path)
● booelan Files.notExists(Path)
● booelan Files.isReadable(Path)
● booelan Files.isWritable(Path)
● booelan Files.isExecutable(Path)
119
Работа с файлами: создание и удаление
● Path Files.createFile(Path)
● Path Files.createDirectory(Path)
● Path Files.createDirectories(Path)
● Path Files.createTempFile(String prefix, String suffix)
● Path Files.createLink(Path, Path)
● Path Files.createSymbolicLink(Path, Path)
● void Files.delete(Path)
● boolean Files.deleteIfExists(Path)
120
Работа с файлами: копирование и перемещение
● Path Files.copy(Path, Path)
● Path Files.move(Path, Path)
121
Работа с файлами: чтение и запись
● byte[] Files.readAllBytes(Path)
● List<String> Files.readAllLines(Path)
● Path Files.write(Path, byte[])
● Path Files.write(Path, Iterable<CharSequence>)
122
java.lang.reflect
● Класс java.lang.Class
● Получение объекта класса Class● new A().getClass();
● Class.forName("A");
● A.class
● Методы● Field[] getFields()
● Method[] getMethods()
● Constructor[] getConstructors()
● isInterface()
● isArray()
123
Многопоточность
124
Потоки выполнения
● Процесс имеет собственный контекст исполнения, собственный набор ресурсов, свою выделенную память.
● Поток (thread) существует внутри процесса, делит память и ресурсы с другими потоками.
● Потоки в JVM● системные потоки:
◊ основной поток виртуальной машины◊ сборщик мусора◊ поток периодических задач◊ поток динамической компиляции
● прикладные потоки
◊ основной поток (main)◊ создаваемые программным путем
125
Класс Thread и интерфейс Runnable
● public class Thread implements Runnable
● 2 варианта создания потока
1) public class A extends Thread {
public void run() { /* тело потока*/ }
}
new A().start;
2) public class A implements Runnable {
public void run() { /* тело потока */ }
}
new Thread(new A()).start();
126
Приостановка и прерывание потока
● try {
Thread.sleep(1000); // спать 1 с
} catch (InterruptedException e) { }
● try {
t.join(1000); // ожидать завершения t в течение 1 с
} catch (InterruptedException e) { }
● t.interrupt(); // устанавливает флаг прерывания
● if (Thread.interrupted() { // сбрасывает флаг
throw new InterruptedException();
}
127
Множественный доступ к переменным
class A {
int counter = 0;
public void up() { counter++; }
public void down() { counter--; }
}
1) получить значение counter
2) увеличить/уменьшить значение на 1
3) сохранить новое значение
1)00
1)00
2) 10
2)-10
3)-1-1
3)11
действиестек
counter
128
Синхронизация
class A {
int counter = 0;
public synchronized void up() { counter++; }
public synchronized void down() { counter--; }
}
● Любой объект имеет монитор
● Поток может выполнить synchronized метод, только захватив монитор
● При выходе из метода поток освобождает монитор
● Для уменьшения времени захвата монитора используются блоки synchronized
synchronized(Object) { }
129
Модификатор volatile
● Переменные класса — общие для всех потоков
● Потоки могут сохранять значения общих переменных в локальном кэше
● Модификатор volatile указывает, что доступ к этой переменной из потоков должен производиться напрямую
130
Взаимодействие потоков
● Методы wait(), notify(), notifyAll()
● Для вызова этих методов поток должен иметь монитор данного объекта, поэтому они вызываются в синхронизированном блоке или методе.
● wait() - поток помещается в список ожидания и освобождает монитор. После выхода из списка ожидания, он может получить монитор, и завершить метод wait.
● notify() - выводит из списка ожидания один из потоков.
● notifyAll() - выводит из списка ожидания все потоки.
131
Диаграмма работы wait/notify
class A {
boolean flag = false;
int value;
synchronized void put(int i) {
while(flag) { wait(); }
flag = true; value = i;
notifyAll();
}
synchronized int get() {
while(!flag) { wait(); }
flag = false;
notifyAll();
return value;
}
}
start() start()
get() BLOCKED
wait()
WAITING put(5)
start() false 0
false 0
false 0
true 5
notify() true 5WAITING
notify()
WAITING
false 5FINISHED
BLOCKED
return 5
FINISHED
132
Состояния потока
new
run()runnable
terminated
blocked
waiting
timedwaiting
start()
диспетчеризация
sleep(time)
wait()notify()
окончание работы
ожидание монитора synchronized
захват монитора synchronized
133
Проблемы многопоточности
● Взаимная блокировка (deadlock)
● Ресурсное голодание (starvation)
● Зацикливание (livelock)
134
пакет java.util.concurrent
● Исполнители● interface Executor : void execute(Runnable)
● interface ExecutorService : Future submit(Callable)
● interface Callable<V> : V call()
● interface Future<V> : V get()
● interface ScheduledExecutorService : ScheduledFuture schedule()
● Реализации● class ThreadPoolExecutor
● class ScheduledThreadPoolExecutor
● Вспомогательный класс● Executors
◊ создание ExecutorService, ScheduledExecutorService, Callable
135
пакет java.util.concurrent.locks
● интерфейс Lock
Lock l = new ReentrantLock();
l.lock(); // tryLock()
try { /* доступ к защищенному ресурсу */ }
finally { l.unlock(); }
● интерфейс Condition
Condition c = l.newCondition();
l.lock();
try {
while(flag) { c.await(); }
flag = true;
c.signal();
} finally { l.unlock(); }
136
пакет java.util.concurrent.atomic
● Содержит классы для реализации атомарных операций
class A {
AtomicInteger counter = new AtomicInteger(0);
public void up() { counter.incrementAndGet(); }
public void down() { counter.decrementAndGet(); }
}
137
java.lang.reflect
● Класс java.lang.Class
● Получение объекта класса Class● new A().getClass();
● Class.forName("A");
● A.class
● Методы● Field[] getFields()
● Method[] getMethods()
● Constructor[] getConstructors()
● isInterface()
● isArray()
138
Вспомогательные классы
139
Лямбда-выражения и функциональные интерфейсы
● λ-выражение — блок кода, предназначенный для объявления анонимной функции.
● λ-выражение — экземпляр функционального интерфейса.
● λ-выражение можно присвоить переменной, типом которой является функциональный интерфейс (целевой тип лямбда-выражения).
● Функциональный интерфейс — интерфейс, в котором определен один и только один абстрактный метод (не считая default и методов Object)
140
Пример
@FunctionalInterface interface Comparator<T> {
public int compare(T obj1, T obj2);
}
public void sort(Comparator<T>) // метод сортировки
class X implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
sort(new X());
sort((String s1, String s2) -> s1.length() - s2.length());
141
Синтаксис λ-выражений
(параметры) -> выражение
(параметры) -> { инструкции; }
(int x, int y) -> x + y
(x, y) -> x * y
() -> 42
(String s) -> System.out.println(s)
x -> x / 2
c -> { int s = c.size(); c.clear(); return s; }
● тип параметров — либо явно, либо из контекста
● может либо возвращать значение, либо не возвращать (void)
● круглые скобки можно опускать, если контекстный параметр один
142
Захват переменных
● Область видимости λ-выражения = область видимости окружающего блока
● В λ-выражении можно использовать только эффективно финальные переменные из окружающего его блока
● λ-выражение захватывает значения переменных из окружающего блока.
● λ-выражение + значения захваченных переменных = замыкание (closure)
public static void repeatMessage(int count, String s) {
Runnable r = () -> {
for (int i = 0; i < count; i++) { println(s); }
}
new Thread(r).start();
}
143
Ссылка на метод
● Если единственное, что делает λ-выражение — вызывает уже существующий метод, его можно заменить на ссылку на метод (method reference)
● s -> A.method(s) ~ A::method
● s -> a.method(s) ~ a::method
● (S s) -> s.method() ~ S::method
● s -> new A(s) ~ A::new
144
Ссылка на метод (пример)
@FunctionalInterface FI { public String func(String s); }
public class Test {
public static String upper(String s) { return s.toUpperCase(); } public String lower(String s) { return s.toLowerCase(); }
public static void trans(FI f, String s) { println(f.func(s)); }
public static void main(String[] args) { Test t = new Test(); trans(Test::upper, "Hello"); // s -> upper(s), "Hello" trans(t::lower, "Hello"); // s -> t.lower(s), "Hello" trans(String::toLowerCase, "Hi"); // s -> s.toLowerCase(), "Hi" trans(String::new, "Hello"); // s -> new String() , "Hello" }}
145
Функциональные интерфейсы
● java.lang.Runnable
void run();
● java.util.Comparator<T>
int compare(T o1, T o2);
● java.util.function.* - набор функциональных интерфейсов общего назначения для разных случаев
146
Пакет java.util.function
● Supplier<R> { R get() }
● Consumer<T> { void accept(T t) }
● Predicate<T> { boolean test(T t) }
● Function<T,R> { R apply(T t) }● UnaryOperator<T> { T apply(T t) }
● BiFunction<T,U,R> { R apply(T t, U u) }● BinaryOperator<T> { T apply(T t1, T t2) }
147
Пакет java.util.function
● int, long, double
● IntSupplier { int getAsInt() }
● IntConsumer { void accept(int value) }
● IntPredicate { boolean test(int value) }
● IntFunction<R> { R apply(int value) }
● IntUnaryOperator { int applyAsInt(int value) }
● IntBinaryOperator { int applyAsInt(int v1, int v2) }
● ToIntFunction<T> { int applyAsInt(T t) }
● ToIntBiFunction<T,U> { int applyAsInt(T t, U u) }
● ObjIntConsumer<T> { accept (T t, int value) }
148
Пакет java.util.stream
● Конвейерная обработка данных
● Поток — последовательность элементов
● Поток может быть последовательным или параллельным
● Конвейер — последовательность операций
149
Конвейеры и коллекции
● Отличия конвейера от коллекции● Элементы не хранятся
● Неявная итерация
● Функциональный стиль — операции не меняют источник
● Большинство операций работают с λ-выраженями
● Ленивое выполнение
● Возможность неограниченного числа элементов
150
Состав конвейера
● Конвейер =● Источник
● Промежуточные операции (0 или больше)
● Завершающая операция
151
Пример
List<String> words
1) long count = 0;
for (String s : words) {
if (s.length() > 5) count++;
}
2) long count = words.stream()
.filter(s -> s.length() > 5)
.count();
152
Источники конвейера
Способы получения потока из источника:
● Collection.stream()
● Collection.parallelStream()
● Arrays.stream(Object[])
● Stream.of(Object[])
● IntStream.range(int, int)
● Stream.empty()
● Stream.generate(Supplier<T> s)
● Stream.iterate(T seed, UnaryOperator<T> f)
153
Промежуточные операции
● Промежуточные операции возвращают поток
● Промежуточные операции выполняются "лениво" — фактически выполнение операции может быть задержано.
● Промежуточные операции делятся на:● Не хранящие состояние (stateless) — выполняются над
элементом вне зависимости от других элементов
● Хранящие состояние (stateful) — выполнение зависит от других элементов (например, сортировка)
154
Завершающие операции
● Завершающие операции возвращают некий результат, либо имеют побочное действие. После завершающей операции поток прекращает существование.
155
Классы и интерфейсы
● интерфейс BaseStream● void close()
● S parallel()
● S sequential()
● S unordered()
● Iterator iterator()
● Spliterator spliterator()
● Интерфейс Stream<T>
● Интерфейсы IntStream, LongStream, DoubleStream
156
Spliterator
● Параллельный Iterator● Spliterator trySplit() — возвращает часть элементов как
отдельный сплитератор
● boolean tryAdvance(Consumer action) — выполнить операцию для очередного элемента
● void forEachRemaining(Consumer action) — выполнить операцию для всех оставшихся элементов
157
Промежуточные операции
● Методы для промежуточных операций (stateless)
● Stream<T> filter (Predicate<T> p)● возвращает поток из элементов, соответствующих условию
● Stream<R> map(Function<T,R> mapper)● преобразует поток элементов T в поток элементов R
● Stream<R> flatMap(Function <T,Stream<R>> mapper)● преобразует каждый элемент потока T в поток элементов R
● Stream<T> peek(Consumer<T> action)● выполняет действие для каждого элемента потока T
158
Промежуточные операции
● Методы для промежуточных операций (stateful)
● Stream<T> distinct()● возвращает поток неповторяющихся элементов
● Stream<T> sorted(Comparator<T> comp)● возвращает отсортированный поток
● Stream<T> limit(long size)● возвращает усеченный поток из size элементов
● Stream<T> skip(long n)● возвращает поток, пропустив n элементов
159
Класс java.util.Optional<T>
● Оболочка, которая может содержать или не содержать значение
● boolean isPresent() - true, если значение есть
● T get() - возвращает значение
● Optional<T> of(T value) — возвращает оболочку со значением
● T orElse(T other) — возвращает значение, если есть, other, если нет
160
Завершающие операции
● void forEach(Consumer<T> action)
● void forEachOrdered(Consumer<T> action)● выполняет действие для каждого элемента потока
● второй вариант гарантирует сохранение порядка элементов
● Optional<T> min(), Optional<T> max()● возвращают минимальный и максимальный элементы,
● long count(), int (long, double) sum()● возвращают количество и сумму элементов
161
Завершающие операции
● T reduce(T identity, BinaryOperator<T> accumulator)● операция редукции — аккумулятор заменяется
T result = identity;
for (T element : stream) {
result = accumulator.apply(result, element);
}
return result;
.stream
.reduce(0, (a, b) -> a + b)
162
Проверки
● boolean anyMatch(Predicate<T> p)● истина, если условие выполняется хотя бы для одного элемента
● При нахождении первого совпадения прекращает проверку
● boolean allMatch(Predicate<T> p)● истина, если условие выполняется для всех элементов.
● При нахождении первого несовпадения прекращает проверку
● boolean noneMatch(Predicate<T> p)● истина, если условие не выполняется ни для одного элемента.
● При нахождении первого совпадения прекращает проверку
163
Пример
public static void main(String[] args) {
List<String> a = Arrays.asList(args);
a.stream()
.filter(s -> s.length() < 5)
.map(String::toUpperCase)
.sorted()
.forEachOrdered(System.out::println);
}
164
Класс java.util.Random
● public Random()
● public Random(long seed)
● nextInt(), nextDouble, nextLong, nextGaussian
● IntStream ints()
● LongStream longs()
● DoubleStream doubles()
165
Регулярные выражения
● Класс Pattern — представляет регулярное выражение
● Класс Matcher — движок, проверяющий соответствие
String regex = "a*b";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("aaabbb");
boolean b = m.matches();
boolean b = Pattern.matches(regex, "aaabbb");
166
Вспомогательные классы
167
Контрольная
1)Классы-оболочки и их применение
2)Основные отличия коллекций HashMap, TreeMap и LinkedHashMap
3)Из каких состояний поток может перейти в состояние «выполняющийся» ?
168
Лямбда-выражения и функциональные интерфейсы
● λ-выражение — блок кода, предназначенный для объявления анонимной функции.
● λ-выражение — экземпляр функционального интерфейса.
● λ-выражение можно присвоить переменной, типом которой является функциональный интерфейс (целевой тип лямбда-выражения).
● Функциональный интерфейс — интерфейс, в котором определен один и только один абстрактный метод (не считая default и методов Object)
169
Пример
@FunctionalInterface interface Comparator<T> {
public int compare(T obj1, T obj2);
}
public void sort(Comparator<T>) // метод сортировки
class X implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
sort(new X());
sort((String s1, String s2) -> s1.length() - s2.length());
170
Синтаксис λ-выражений
(параметры) -> выражение
(параметры) -> { инструкции; }
(int x, int y) -> x + y
(x, y) -> x * y
() -> 42
(String s) -> System.out.println(s)
x -> x / 2
c -> { int s = c.size(); c.clear(); return s; }
● тип параметров — либо явно, либо из контекста
● может либо возвращать значение, либо не возвращать (void)
● круглые скобки можно опускать, если контекстный параметр один
171
Захват переменных
● Область видимости λ-выражения = область видимости окружающего блока
● В λ-выражении можно использовать только эффективно финальные переменные из окружающего его блока
● λ-выражение захватывает значения переменных из окружающего блока.
● λ-выражение + значения захваченных переменных = замыкание (closure)
public static void repeatMessage(int count, String s) {
Runnable r = () -> {
for (int i = 0; i < count; i++) { println(s); }
}
new Thread(r).start();
}
172
Ссылка на метод
● Если единственное, что делает λ-выражение — вызывает уже существующий метод, его можно заменить на ссылку на метод (method reference)
● s -> A.method(s) ~ A::method
● s -> a.method(s) ~ a::method
● (S s) -> s.method() ~ S::method
● s -> new A(s) ~ A::new
173
Ссылка на метод (пример)
@FunctionalInterface FI { public String func(String s); }
public class Test {
public static String upper(String s) { return s.toUpperCase(); } public String lower(String s) { return s.toLowerCase(); }
public static void trans(FI f, String s) { println(f.func(s)); }
public static void main(String[] args) { Test t = new Test(); trans(Test::upper, "Hello"); // s -> upper(s), "Hello" trans(t::lower, "Hello"); // s -> t.lower(s), "Hello" trans(String::toLowerCase, "Hi"); // s -> s.toLowerCase(), "Hi" trans(String::new, "Hello"); // s -> new String() , "Hello" }}
174
Функциональные интерфейсы
● java.lang.Runnable
void run();
● java.util.Comparator<T>
int compare(T o1, T o2);
● java.util.function.* - набор функциональных интерфейсов общего назначения для разных случаев
175
Пакет java.util.function
● Supplier<R> { R get() }
● Consumer<T> { void accept(T t) }
● Predicate<T> { boolean test(T t) }
● Function<T,R> { R apply(T t) }● UnaryOperator<T> { T apply(T t) }
● BiFunction<T,U,R> { R apply(T t, U u) }● BinaryOperator<T> { T apply(T t1, T t2) }
176
Пакет java.util.function
● int, long, double
● IntSupplier { int getAsInt() }
● IntConsumer { void accept(int value) }
● IntPredicate { boolean test(int value) }
● IntFunction<R> { R apply(int value) }
● IntUnaryOperator { int applyAsInt(int value) }
● IntBinaryOperator { int applyAsInt(int v1, int v2) }
● ToIntFunction<T> { int applyAsInt(T t) }
● ToIntBiFunction<T,U> { int applyAsInt(T t, U u) }
● ObjIntConsumer<T> { accept (T t, int value) }
177
Класс java.util.Random
● public Random()
● public Random(long seed)
● nextInt(), nextDouble, nextLong, nextGaussian
● IntStream ints()
● LongStream longs()
● DoubleStream doubles()
178
Регулярные выражения
● Класс Pattern — представляет регулярное выражение
● Класс Matcher — движок, проверяющий соответствие
String regex = "a*b";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("aaabbb");
boolean b = m.matches();
boolean b = Pattern.matches(regex, "aaabbb");
179
Графический интерфейс
180
AWT, Swing, SWT, JavaFX
● AWT — Abstract Window Toolkit● библиотека, зависимая от графической подсистемы ОС
● разный вид на разных платформах
● Swing● надстройка над AWT в виде легковесных Java-компонентов
● изменяемый вид компонентов
● SWT● Часть Eclipse, компоненты-оболочки для компонентов ОС
● Недостающий функционал написан на Java
● JavaFX ● новая графическая библиотека с улучшенной поддержкой
анимации и визуальных эффектов, возможностью задания интерфейса с помощью XML и стилей с помощью CSS
181
Создание графических приложений
1) Создание главного окна
2) Создание остальных компонентов интерфейса
3) Размещение компонентов интерфейса в главном окне
4) Обеспечение реакции компонентов на события
182
Класс java.awt.Component
● Компонент — отображаемый и взаимодействующий с пользователем элемент GUI
● java.awt.Component - абстрактный класс — элемент GUI
● задает размер, цвет, область отображения
● порождает основные события
183
Методы класса Component
● Цвет текста и цвет фона
Color getForeground() void setForeground(Color)
Color getBackground() void setBackground(Color)
● Класс Color● Константы Color.BLACK, Color.WHITE, Color.RED ...
● Конструкторы Color(r, g, b [,a]), Color(int [,boolean])
◊ r,g,b,[a] — int (0-255), float (0.0-1.0), int (0x[AA]RRGGBB)
● Методы
◊ getRed(), getGreen(), getBlue(), getAlpha()◊ brighter(), darker()
184
Методы класса Component
● Шрифт
Font getFont() void setFont(Font)
● Класс Font● физические (Arial, Times) и логические (Dialog, DialogInput, Serif,
SansSerif, Monospaced)
● Константы:
◊ Font.DIALOG, Font.MONOSPACED, Font.SERIF, Font.SANS_SERIF◊ Font.PLAIN, Font.BOLD, Font.ITALIC
● Конструктор Font(String name, int style, int size)
● Методы
◊ String getFontName(), int getStyle(), int getSize()
185
Методы класса Component
● Положение и размеры
void setBounds(Rectangle) Rectangle getBounds()
void setLocation(Point) Point getLocation()
void setSize(Dimension) Dimension getSize()
● Класс Point (int x, int y)● getX(), getY(), setLocation(x,y)
● Класс Dimension (int height, int width)● getHeight(), getWidth(), setSize(h, w)
● Класс Rectangle (int x, int y, int height, int width)● getX(), getY(), getHeight(), getWIdth(), getLocation(), getSize()
● setLocation(x,y), setSize(h,w), setBounds(x,y,h,w)
186
Методы класса Component
● Видимость и активность
boolean isVisible() void setVisible(boolean)
boolean isEnabled() void setEnabled(boolean)
● Компоненты изначально видимы, кроме основных окон, им надо явно вызывать метод setVisible(true)
● Компоненты изначально активны (воспринимают действия пользователя и порождают события)
187
Методы класса Component
● Дополнительное рисование
void paint(Graphics) void update(Graphics) void repaint()
● Graphics — графический контекст компонента
● Метод paint должен содержать весь код отрисовки
● 2 варианта вызова paint — системный и программный
● Системный — первое отображение, изменение размера, необходимость перерисовки
● JVM вызывает paint(Graphics)
● Программный — изменение состояния компонента
● в программе вызывается repaint()● регистрируется событие отрисовки● JVM вызывает update(Graphics)
188
Класс java.awt.Container
● Контейнер — компонент, на котором располагаются другие компоненты
● extends java.awt.Component
● Компонент может находиться только в одном контейнере
● Методы:● add(Component)
● setLayout(LayoutManager)
● validate()
189
Основные компоненты и контейнеры AWT
java.lang.Object
java.awt.Component
Label
Choice
List
Button
Checkbox
Scrollbar
Canvas
TextComponent
TextAreaTextField
MenuComponent
MenuItem MenuBar
Menu
CheckboxMenuItem
PopupMenu
Container
PanelWindow
DialogFrame
190
Менеджер компоновки
● Интерфейс LayoutManager● Container.setLayout(LayoutManager)
● Container.add(Component)
● Интерфейс LayoutManager2● Container.setLayout(LayoutManager2, Object constraints)
● Container.add(Component, Object constraint)
● Расстановка элементов● Container.validate()
● Container.invalidate()
● Управление размером компонентов● Component.getPreferredSize()
● Component.getMinimumSize()
● Component.getMaximumSize()
191
FlowLayout
● Заполнение контейнера слева направо (или справа налево) построчно
● Компоненты сохраняют свой размер preferredSize
● Управление размещением:● setHgap(int), setVgap(int) // 5
● setAlignment(LEFT, RIGHT, CENTER) // CENTER
1 2 3
4
192
GridLayout
● Контейнер делится одинаковые ячейки по строкам и столбцам
● Все компоненты будут одного размера
● GridLayout(int rows, int cols)
● Управление размещением:● setHgap(int), setVgap(int) // 0
● setRows(int), setColumns(int) // 1, 0
1 2 3
4
193
GridBagLayout
● Контейнер делится на ячейки по строкам и столбцам
p.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridX = 0; c.gridY = 0; c.fill = GridBagConstraints.BOTH;
p.add(new Button("1"), c);
c.gridX = GridBagConstraints.RELATIVE;
p.add(new Button("2"), c); p.add(bew Button("3"), c);
c.gridY = 1; c.gridX = 1; c.gridWidth = 2;
c.fill = GridBagConstraints.NONE; p.add(new Button("4"), c);
1 2 3
4
194
CardLayout
● Несколько компонентов отображаются в одном месте
CardLayout cl = new CardLayout();
p.setLayout(cl);
p.add(new Button("1"), "Card1");
p.add(new Button("2"), "Card2");
cl.show(p,"Card1");
cl.show(p,"Card2");
1
2
195
BorderLayout
● Компоненты располагаются в 5 областях
● p.add(new Button("1"), BorderLayout.NORTH);
BorderLayout.NORTH
BorderLayout.SOUTH
BorderLayout.NORTH
BorderLayout.WEST
BorderLayout.EASTBorderLayout.CENTER
196
Обработка событий
● Источник события — любой компонент
● Событие — потомок класса AWTEvent
● Обработчик события — реализует интерфейс XListener и соответствующие методы, в которых располагается код обработки события. Методу передается объект события
class A implements ActionListener {
Button b = new Button("OK");
Label l = new Label("Button pressed");
l.setVisible(false);
b.addActionListener(this);
......
public void actionPerformed(ActionEvent e) {
l.setVisible("true");
}
197
Обработка событий анонимным классом
class A {
Button b = new Button("OK");
final Label l = new Label("Button pressed");
l.setVisible(false);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
l.setVisible("true");
}
});
198
Обработка событий
● Компонент регистрирует слушателей в списке
● При наступлении события у всех слушателей из списка вызывается метод, соответствующий событию
● В объекте события хранится информация об источнике события (getSource), времени его наступления (getWhen) и другая информация, зависящая от типа события (например, координаты клика мышки)
● Низкоуровневые события — KeyEvent, MouseEvent, MouseMotionEvent
● Семантические события — ActionEvent, ItemEvent
199
MouseListener, MouseMotionListener, MouseEvent
● MouseListener● mousePressed(MouseEvent)
● mouseReleased(MouseEvent)
● mouseClicked(MouseEvent)
● mouseEntered(MouseEvent)
● mouseExited(MouseEvent)
● MouseMotionListener● mouseDragged(MouseEvent)
● mouseMoved(MouseEvent)
● MouseEvent● getPoint()
● getLocationOnScreen()
● getButton()
● getClickCount()
200
Классы-адаптеры
● class X implements MouseListener {
public void mousePressed(MouseEvent e) {
// обработка нажатия кнопки мыши
}
// обработка других событий не требуется
public void mouseClicked(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
....
}
● class Y extends MouseAdapter {
public void mousePressed(MouseEvent e) { ... }
}
201
KeyListener, KeyEvent
● KeyListener● keyPressed(KeyEvent)
● keyReleased(KeyEvent)
● keyTyped(KeyEvent)
● KeyEvent● getKeyChar() // для keyTyped()
● getKeyCode() // для keyPressed, keyReleased
● getModifiers() // Shift, Alt, Ctrl, Meta ...
● getKeyLocation() // Standard, Left, Right, Numpad, Unknown
202
WindowListener, WindowEvent
● WindowListener● windowOpened(WindowEvent)
● windowClosing(WindowEvent)
● windowClosed(WindowEvent)
● windowActivated(WindowEvent)
● windowDeactivated(WindowEvent)
● windowIconified(WindowEvent)
● windowDeiconified(WindowEvent)
● WindowEvent● getNewState()
● getOldState()
● getOppositeWindow()
203
ActionListener, ActionEvent
● ActionListener● actionPerformed(ActionEvent)
● ActionEvent● нажата кнопка
● двойной клик в списке
● выбор пункта меню
● клавиша Enter в текстовом поле
204
AdjustmentListener, AdjustmentEvent
● AdjustmentListener● adjustmentValueChanged(AdjustmentEvent)
● AdjustmentEvent● int getValue()
● boolean getValueIsAdjusting()
205
ItemListener, ItemEvent
● ItemListener● itemStateChanged(ItemEvent)
● ItemEvent● Object getItem()
● int getStateChange() // selected-deselected
● установка-сброс флажка
● установка-сброс пункта меню
● выбор элемента списка
206
TextListener, TextEvent
● TextListener● textValueChanged(TextEvent)
● TextEvent● изменился текст в текстовом компоненте
207
Основные компоненты Swing
java.lang.Object
javax.swing.JComponent
JLabel
JComboBox
JList
JCheckbox
JScrollBar
JPanel
JTextComponent
JTextAreaJTextField
AbstractButton
JMenuItem JMenuBar
JMenu
JCheckboxMenuItem
JRadioButtonMenuItem
java.awt.Container
Window
DialogFrame
java.awt.Component
JFrame
JWindow
JDialog
JButton
JRadioButton
JToggleButton
JTable
JTree
208
JFrame
● Не является легковесным компонентом — это окно ОС
● Содержит набор панелей для размещения компонентов
● При создании — невидимый
● JFrame.add() = JFrame.getContentPane.add()
JFrameJRootPane
JLayeredPaneJMenuBar
contentPaneglassPane
209
Организация приложения Swing
public class Main {
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui();
}
});
}
private void gui() {
JFrame f = new JFrame();
...
f.setVisible(true);
}
}
210
JFrame
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JLabel("Hello!"), BorderLayout.CENTER);
f.setJMenuBar(new JMenuBar());
f.pack(); // установка размеров фрейма
f.setVisible(true);
211
JComponent
● extends java.awt.Container — может содержать картинку
● всплывающие подсказки — setToolTipText()
● построение основано на шаблоне MVC
● встроенная двойная буферизация при отрисовке
● реализация метода paint
void paint(Graphics g) { paintComponent(g); paintBorder(g); paintChildren(g);}
● Для отрисовки нужно переопределить paintComponent(g)
● Необходимо вызывать super.paintComponent(g);
212
MVC и Swing
● MVC — Model, View, Controller
● Модель отвечает за поведение
● Представление — отвечает за отображение
● Контроллер — связывает модель и представление и управляет ими
● Реализация Swing — Model + UI Delegate
● UI Delegate = View + Controller
● Модель может быть визуальной или моделью данных
● Одну модель данных можно назначить разным компонентам
● В случае большого числа событий можно использовать ChangeEvent — изменение в модели.
213
Модели и делегаты
● Модели — интерфейсы: ButtonModel, ListModel, ...
● Реализации моделей по умолчанию — классы, например: DefaultListModel, DefaultTableModel
● Для сложных моделей дополнительно имеются классы абстрактных моделей, предназначенные для облегчения написания своих классов на их основе. Например, AbstractTableModel, AbstractTreeModel
● Делегаты — потомки класса javax.swing.plaf.ComponentUI, например, ButtonUI, ListUI
● Для управления делегатами предназначен класс javax.swing.UIManager
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
214
Менеджеры компоновки Swing
● BoxLayout● Компоненты располагаются в один ряд вертикально или
горизонтально
● Класс Box — контейнер с BoxLayout
● Box.createHorizontalBox()
● Box.createVerticalBox()
● createRigidArea(Dimension)
● createHorizontalGlue()
● createVerticalGlue()
● Filler(minSize, prefSize, maxSize)
215
Менеджеры компоновки Swing
● GroupLayout● Все компоненты описываются дважды — горизонтальное
расположение и вертикальное расположение
● Все компоненты являются участниками групп — последовательных и параллельных
GroupLayout gl = new GroupLayout(p);gl.setVerticalGroup( gl.createSequentialGroup() .addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(c1) .addComponent(c2) .addComponent(c3)) .addComponent(c4));
gl.setHorizontalGroup( gl.createSequentialGroup() .addComponent(c1) .addGroup(gl.createParallelGroup(GroupLayout.Alignment.LEADING) .addCompoment(c2) .addComponent(c4)) .addComponent(c3));
с1 с2 с3
с4
216
Менеджеры компоновки Swing
● SpringLayout● Все компоненты соединены пружинами (Spring), которые имеют
минимальную, максимальную и предпочтительную длину
● Между краями соседних компонентов устанавливаются соответствующие пружины, в итоге получается компоновка, в определенных пределах растягивающаяся и сжимающаяся
● Обычно используется автоматическими расстановщиками
с1 с2 с3
с4
217
JLabel
● Метка изначально прозрачная. Если нужна непрозрачная метка, то вызывается метод setOpaque(true)
218
JTextField, JTextArea
● Конструктор принимает строку
● Могут быть редактируемыми и нет
● События — ActionEvent, DocumentEvent
219
JButton, JCheckBox, JRadioButton
● Конструктор принимает строку
● Для JCheckBox и JRadioButton — еще состояние (boolean)
● JRadioButton используется в группе ButtonGroup
● События — ● ActionEvent для JButton, JRadioButton
● ItemEvent для JCheckBox (позволяет отследить select-deselect)
● Модель — DefaultButtonModel — элемент с двумя состояниями
● Почти так же обрабатываются JMenuItem, JMenu, JCheckBoxMenuItem, JRadioButtonMenuItem
220
JList
● Конструктор принимает массив или вектор объектов
● Основное событие — ListSelectionEvent
● Модель DefaultListModel — модель данных (вектор), DefaultListSelectionModel — модель вариантов выбора (одиночный, интервальный, множественный)
221
JComboBox
● Может быть редактируемым и нередактируемым
● Конструктор принимает массив или вектор объектов
● Основное событие — ActionEvent, иногда ItemEvent
● Модель DefaultComboBoxModel реализует 3 интерфейса — ListModel, ComboBoxModel и MutableComboBoxModel.
● По сравнению с ListModel — ComboBoxModel вводит понятие выбранный элемент (отображаемый)
222
JSpinner
● Составной компонент — 2 кнопки и редактор значений
● Конструктор принимает модель SpinnerModel
● Основное событие — ChangeEvent
● 3 готовых модели — SpinnerListModel, SpinnerDateModel, SpinnerNumberModel + AbstractSpinnerModel
● 3 готовых редактора — JSpinner.ListEditor, JSpinner.DateEditor, JSpinner.NumberEditor
223
JSlider
● Составной компонент — 2 кнопки и редактор значений
● Конструктор принимает min и max значения
● Основное событие — ChangeEvent
● Модель — DefaultBoundedRangeModel — еще используется для JProgressBar
224
JPanel
● Универсальный контейнер
● По умолчанию — FlowLayout
225
AWT, Swing, SWT, JavaFX
● AWT — Abstract Window Toolkit● библиотека, зависимая от графической подсистемы ОС
● разный вид на разных платформах
● Swing● надстройка над AWT в виде легковесных Java-компонентов
● изменяемый вид компонентов
● SWT● Часть Eclipse, компоненты-оболочки для компонентов ОС
● Недостающий функционал написан на Java
● JavaFX ● новая графическая библиотека с улучшенной поддержкой
анимации и визуальных эффектов, возможностью задания интерфейса с помощью XML и стилей с помощью CSS
226
Основные концепции SWT
● Компоненты интерфейса (виджеты) — по возможности виджеты ОС
● Коммуникации между JVM и виджетами — с помощью JNI (Java Native Interface)
● Если виджет недоступен в ОС — он эмулируется JVM
227
Виджеты
● Класс org.eclipse.swt.widgets.Widget — предок всех элементов интерфейса.
● Виджеты создаются, уничтожаются, извещают о событиях
● Класс Control — предок оконных элементов управления
● Класс Item — предок всех неоконных элементов, которые распологаются внутри элементов управления
● Пакет org.eclipse.swt.widgets — виджеты ОС
● Пакет org.eclipse.swt.custom — виджеты Java
228
Composite
● Элементы управления, которые могут содержать другие элементы управления
● Аналог контейнера в Swing
229
Display, Shell
● org.eclipse.swt.widgets.Display — класс-прослойка между SWT и ОС.
● Дисплей обеспечивает цикл обработки событий.
● Shell — класс, представляющий окно, которым управляет менеджер окон.
● Окно, связанное с дисплеем — окно верхнего уровня.
● Окно, связанное с другим окном — диалог.
230
Цикл обработки событий
Display display = new Display();
Shell sh = new Shell(display);
sh.setLayout(new FillLayout());
Label l = new Label(sh, SWT.BORDER);
l.setText("Hello!");
l.pack
sh.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
231
Класс org.eclipse.swt.SWT
● Содержит стили виджетов
● Button button = new Button(shell, SWT.PUSH);
232
Обработка событий
Button b = new Button(sh, SWT.PUSH);
b.setText("Press me");
b.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
l.setText("Goodbye!");
}
});
b.pack();
233
JavaFX
234
JavaFX
● JavaFX — новая библиотека для разработки RIA (Rich Internet Applications)
● Поддержка XML для создания интерфейса
● Поддержка стилей CSS
● Поддержка 2D- и 3D-графики ● Prism — поддерживает DirectX, OpenGL, аппаратное ускорение
● GWT (Glass Windowing Toolkit) — связь с ОС
● Quantum — управление потоками, связь Prism и GWT
● Легковесные компоненты
● Интеграция с библиотекой Swing
235
javafx.application
● javafx.application.Application — класс-предок всех приложений JavaFX
● void init() — инициализация приложения (стартовый поток)
● abstract void start(Stage s) — основной поток приложения
● void stop() — освобождение ресурсов
● public static void launch(String args) — запуск приложения
236
javafx.stage
● javafx.stage.Stage — основная платформа
● Контейнер верхнего уровня (аналог Jframe)
● Предоставляется системой при запуске приложения
● Обеспечивает связь с графической подсистемой ОС● setTitle(String)
● setScene(Scene)
● show()
237
javafx.scene
● javafc.scene.Scene — контейнер для элементов сцены
● Должен быть хотя бы один объект класса Scene
● Элементы сцены — узлы (Node)
● Узлы образуют граф (scene graph)
● Граф включает не только контейнеры и компоненты, но также графические примитивы (текст и графические примитивы)
● Узел с дочерними узлами — Parent (extends Node)
● Корневой узел (root node) — узел без родительского узла
● Scene sc = new Scene(root node,300,150);
238
Node
● Свойства (properties)● String id
● Parent (только один)
● Scene
● Стиль (styleClass, style)
● Видимость, активность, прозрачность
● Размеры (min, max, preferred)
● Границы (bouundsInLocal, boundsInParent, layoutBouunds)
● Трансформации (сдвиг, вращение, масштаб, наклон)
● Эффекты
● События (mouse, key, drag, touch, rotate, scroll, swipe, zoom)
239
Основные компоненты JavaFX
Node
Slider
ComboBoxBase
ListView
Checkbox
ScrollBar
Spinner
TextInputControl
TextAreaTextField
Labeled
Cell Label
Region
Pane
Parent
ButtonBase
Hyperlink
ToggleButton
TableView
TreeView
FlowPane
BorderPane
StackPane
GridPane
Button
RadioButton
DateCellIndexedCell
ListCell
TableCell
TreeCell
Canvas ImageView Shape2D
Chart
Group WebView
Control
Shape3D
240
Hello World!
import javafx.application.*;import javafx.stage.*;import javafx.scene.*;import javafx.scene.control.*;import javafx.scene.layout.*;
public class Hello extends Application { public void start(Stage stage) { FlowPane fp = new FlowPane(); fp.getChildren().add(new Label("Hello World!")); stage.setScene(new Scene(fp,100,200)); stage.show(); } public static void main(String... args) { launch(args); }}
241
Контейнеры с компоновкой
● BorderPane — top, bottom, left, right, center
● HBox, VBox — в один ряд по горизонтали/вертикали
● StackPane — один над другим
● GridPane — сетка (таблица)
● FlowPane — последовательно с переносом
● TilePane — равномерные ячейки
● AnchorPane — привязка к границам родителя
242
Обработка событий
● Событие: javafx.event.Event● ActionEvent extends Event
● Обработчик: javafx.event.EventHandler<T extends Event>● void handle(T event)
● Регистрация: ● setOnAction(EventHandler<T>)
Label label = new Label();
Button button = new Button("Нажми меня");
button.setOnAction((ae) → { label.setText("Спасибо");} )
243
Приложение Swing
import javax.swing.*;import java.awt.*;import java.awt.event.*;
public class SwingApp { public SwingApp() { JFrame frame = new JFrame("Hello"); JLabel label = new JLabel(""); JButton button = new JButton("OK"); frame.getContentPane().setLayout(new FlowLayout()); frame.getContentPane().add(label); frame.getContentPane().add(button); button.addActionListener((ae) -> {label.setText("Привет!");}); frame.setSize(240, 120); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> { new SwingApp(); }); }}
244
Приложение SWT
import org.eclipse.swt.events.*;import org.eclipse.swt.widgets.*;import org.eclipse.swt.layout.*;import org.eclipse.swt.*;
public class SWTApp { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setText("Hello"); shell.setSize(240,120); shell.setLayout(new FillLayout(SWT.HORIZONTAL)); Label label = new Label(shell,SWT.BORDER); Button button = new Button(shell, SWT.PUSH); button.setText("OK"); button.pack(); label.pack(); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { label.setText("Привет!"); } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); }}
245
Приложение JavaFX
import javafx.application.*;import javafx.event.*;import javafx.geometry.Pos;import javafx.scene.control.*;import javafx.scene.*;import javafx.stage.*;import javafx.scene.layout.*;import javafx.scene.effect.*;
public class FXApp extends Application { public void start(Stage stage) { stage.setTitle("Hello"); FlowPane root = new FlowPane(); Label label = new Label(; Button button = new Button("OK"); root.getChildren().add(label); root.getChildren().add(button); button.setOnAction((ae) -> label.setText("Привет!")); stage.setScene(new Scene(root,240,120)); stage.show(); } public static void main(String... args) { launch(args); }}
246
Конвейерная обработка данных
247
Пакет java.util.stream
● Конвейерная обработка данных
● Поток — последовательность элементов
● Поток может быть последовательным или параллельным
● Конвейер — последовательность операций
248
Конвейеры и коллекции
● Отличия конвейера от коллекции● Элементы не хранятся
● Неявная итерация
● Функциональный стиль — операции не меняют источник
● Большинство операций работают с λ-выраженями
● Ленивое выполнение
● Возможность неограниченного числа элементов
249
Состав конвейера
● Конвейер =● Источник
● Промежуточные операции (0 или больше)
● Завершающая операция
250
Пример
List<String> words
1) long count = 0;
for (String s : words) {
if (s.length() > 5) count++;
}
2) long count = words.stream()
.filter(s -> s.length() > 5)
.count();
251
Источники конвейера
Способы получения потока из источника:
● Collection.stream()
● Collection.parallelStream()
● Arrays.stream(Object[])
● Stream.of(Object[])
● IntStream.range(int, int)
● Stream.empty()
● Stream.generate(Supplier<T> s)
● Stream.iterate(T seed, UnaryOperator<T> f)
252
Промежуточные операции
● Промежуточные операции возвращают поток
● Промежуточные операции выполняются "лениво" — фактически выполнение операции может быть задержано.
● Промежуточные операции делятся на:● Не хранящие состояние (stateless) — выполняются над
элементом вне зависимости от других элементов
● Хранящие состояние (stateful) — выполнение зависит от других элементов (например, сортировка)
253
Завершающие операции
● Завершающие операции возвращают некий результат, либо имеют побочное действие. После завершающей операции поток прекращает существование.
254
Классы и интерфейсы
● интерфейс BaseStream● void close()
● S parallel()
● S sequential()
● S unordered()
● Iterator iterator()
● Spliterator spliterator()
● Интерфейс Stream<T>
● Интерфейсы IntStream, LongStream, DoubleStream
255
Spliterator
● Параллельный Iterator● Spliterator trySplit() — возвращает часть элементов как
отдельный сплитератор
● boolean tryAdvance(Consumer action) — выполнить операцию для очередного элемента
● void forEachRemaining(Consumer action) — выполнить операцию для всех оставшихся элементов
256
Промежуточные операции
● Методы для промежуточных операций (stateless)
● Stream<T> filter (Predicate<T> p)● возвращает поток из элементов, соответствующих условию
● Stream<R> map(Function<T,R> mapper)● преобразует поток элементов T в поток элементов R
● Stream<R> flatMap(Function <T,Stream<R>> mapper)● преобразует каждый элемент потока T в поток элементов R
● Stream<T> peek(Consumer<T> action)● выполняет действие для каждого элемента потока T
257
Промежуточные операции
● Методы для промежуточных операций (stateful)
● Stream<T> distinct()● возвращает поток неповторяющихся элементов
● Stream<T> sorted(Comparator<T> comp)● возвращает отсортированный поток
● Stream<T> limit(long size)● возвращает усеченный поток из size элементов
● Stream<T> skip(long n)● возвращает поток, пропустив n элементов
258
Класс java.util.Optional<T>
● Оболочка, которая может содержать или не содержать значение
● boolean isPresent() - true, если значение есть
● T get() - возвращает значение
● Optional<T> of(T value) — возвращает оболочку со значением
● T orElse(T other) — возвращает значение, если есть, other, если нет
259
Завершающие операции
● void forEach(Consumer<T> action)
● void forEachOrdered(Consumer<T> action)● выполняет действие для каждого элемента потока
● второй вариант гарантирует сохранение порядка элементов
● Optional<T> min(), Optional<T> max()● возвращают минимальный и максимальный элементы,
● long count(), int (long, double) sum()● возвращают количество и сумму элементов
260
Завершающие операции
● T reduce(T identity, BinaryOperator<T> accumulator)● операция редукции — аккумулятор заменяется
T result = identity;
for (T element : stream) {
result = accumulator.apply(result, element);
}
return result;
.stream
.reduce(0, (a, b) -> a + b)
261
Проверки
● boolean anyMatch(Predicate<T> p)● истина, если условие выполняется хотя бы для одного элемента
● При нахождении первого совпадения прекращает проверку
● boolean allMatch(Predicate<T> p)● истина, если условие выполняется для всех элементов.
● При нахождении первого несовпадения прекращает проверку
● boolean noneMatch(Predicate<T> p)● истина, если условие не выполняется ни для одного элемента.
● При нахождении первого совпадения прекращает проверку
262
Пример
public static void main(String[] args) {
List<String> a = Arrays.asList(args);
a.stream()
.filter(s -> s.length() < 5)
.map(String::toUpperCase)
.sorted()
.forEachOrdered(System.out::println);
}
263
Сетевое взаимодействие
264
Сетевое взаимодействие
● Соединение клиент-сервер● Сервер предоставляет данные по запросу клиента
● IP-адрес и порт
● Протоколы транспортного уровня — TCP и UDP● TCP
◊ устанавливается соединение◊ подтверждение доставки◊ надежность передачи данных
● UDP
◊ без установление соединения◊ без подтверждения доставки◊ скорость передачи данных
● Протокол прикладного уровня - HTTP
265
IP-адреса и DNS
● IPv4 и IPv6
● Класс InetAddress (Inet4Address, Inet6Address)
● DNS — Domain Name Service
● Методы InetAddress (статические)● InetAddress getLocalHost()
● InetAddress getByAddress(byte[] addr)
● InetAddress getByName(String name) — обращение к DNS
● Нестатические методы● byte[] getAddress
● String getHostName()
266
Обмен по протоколу UDP
● java.net.DatagramPacket — дейтаграмма (передаваемые данные + служебная информация)
● java.net.DatagramSocket — сокет для обмена
● java.nio.channels.DatagramChannel — сетевой канал
267
Пример обмена по протоколу UDP
DatagramPacket i = new DatagramPacket(b, b.length);s.receive(i);
DatagramPacket i = new DatagramPacket(b, b.length);s.receive(i);
// сервер
byte b[] = new byte[10];
// клиент
byte b[] = {0,1,2,3,4,5,6,7,8,9};
SocketAddress a = new InetSocketAddress(ADDR, PORT);DatagramSocket s = new DatagramSocket();
DatagramPacket o = new DatagramPacket(b, b.length, i.getAddress(), i.getPort());s.send(o);
DatagramPacket o = new DatagramPacket(b, b.length, a);s.send(o);
SocketAddress a = new InetSocketAddress(PORT);DatagramSocket s = new DatagramSocket();
for (byte i : b) { System.out.println(b);}
for (int i = 0; i < 10; i++) { b[i] *= 2;}
268
Пример обмена по протоколу UDP
f.clear();a = s.receive(f);
// сервер
byte b[] = new byte[10];
// клиент
byte b[] = {0,1,2,3,4,5,6,7,8,9};
SocketAddress a = new InetSocketAddress(ADDR, PORT);DatagramChannel s = DatagramChannel.open();s.bind(null);ByteBuffer f = ByteBuffer.bind(b);
f.flip();s.send(f, a);
SocketAddress a = new InetSocketAddress(PORT);DatagramChannel s = DatagramChannel.open();s.bind(a);ByteBuffer f = ByteBuffer.bind(b);
for (byte i : b) { System.out.println(b);}
for (int i = 0; i < 10; i++) { b[i] *= 2;}
f.clear();a = s.receive(f);
f.flip();s.send(f, a);
269
Обмен по протоколу TCP
● java.net.Socket — сокет для обмена
● java.net.ServerSocket — фабрика сокетов
● обмен данными через потоки ввода-вывода
● java.nio.channels.SocketChannel — сетевой канал
270
Пример обмена по протоколу TCP
InputStream i = s.getInputStream();i.read(b);
Socket s = new Socket(ADDR, PORT);
OutputStream o = s.getOutputStream();o.write(b);
OutputStream o = s.getOutputStream();o.write(b);
ServerSocket ss = new ServerSocket(PORT);Socket s = ss.accept();
Arrays.stream(b) .forEach(System.out::println());
InputStream i = s.getInputStream();i.read(b);
// сервер
byte b[] = new byte[10];
// клиент
byte b[] = {0,1,2,3,4,5,6,7,8,9};
i.close(); o.close(); s.close(); i.close(); o.close(); s.close();ss.close();
for (int i = 0; i < 10; i++) { b[i] *= 2;}
271
Пример обмена по протоколу TCP (NIO)
OutputStream o = s.getOutputStream();o.write(b);
InputStream i = s.getInputStream();i.read(b);
// сервер
byte b[] = new byte[10];
// клиент
byte b[] = {0,1,2,3,4,5,6,7,8,9};
s.close(); s.close();ss.close();
SocketAddress a = new InetSocketAddress(ADDR, PORT);
SocketChannel s = SocketChannel.open(a);ByteBuffer f = ByteBuffer.bind(b);
SocketAddress a = new InetSocketAddress(PORT);ServerSocketChannel ss = ServerSocketChannel.open();ss.bind(a);SocketChannel s = ss.accept();
ByteBuffer f = ByteBuffer.bind(b);
f.clear();a = s.read(f);
f.flip();s.write(f, a);
for (int i = 0; i < 10; i++) { b[i] *= 2;}
f.clear();a = s.read(f);
f.flip();s.write(f, a);
272
Протокол HTTP
URL url = new URL("http://www.google.com");
InputStream is = url.openStream();
// is.read();
is.close();
URLConnection uc = url.getConnection();
uc.connect();
InputStream is = uc.getInputStream();
// is.read();
is.close();
uc.close()
273
Шаблоны проектирования
274
● Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-оринтированного проектирования. Паттерны проектирования
GoF — Gang of Four = Банда четырех
● Основные
● Порождающие
● Структурные
● Поведенческие
275
Delegation
● Делегирование можно использовать вместо наследования в случаях динамического изменения поведения класса.
A
Role
A Delegate
m() m()
class A { public m() { }}
class Delegate { A obj;
public m() { return obj.m(); }
Interface / Abstract Superclass
● Интерфейс убирает зависимость от реализации конкретного класса
● Наследование от абстрактного класса позволяет задавать общее поведение конкретных потомков
● TableModel <- AbstractTableModel <- DefaultTableModel
Client <<interface>> Service
AbstractService
DefaultService
Immutable
● Основное использование — простая реализация параллельного доступа к объекту без синхронизации
● Запрещено изменять состояние объекта после его создания
● Если необходимо новое состояние объекта — создается новый объект
● String
Marker Interface
● Показывает, реализует ли класс некоторое свойство
● Маркер — интерфейс без методов
● Serializable
Factory Method
● Класс должен инициировать создание объектов, не имея информации о классах создаваемых объектов
Client<<interface>> Product <<interface>> Factory
ConcreteFactoryConcreteProduct
Product factoryMethod()
Product factoryMethod()
Abstract Factory
● Необходимо создание множества совместно использующихся объектов
Client
<<interface>> P1
<<interface>> Factory
FactoryA
P1A
P1 createP1()P2 createP2()
<<interface>> P2
FactoryBP1B
P2A
P2B
Builder
● Создание сложных объектов на основании только типа и содержимого без знания деталей реализации
Client<<interface>> Product
AbstractBuilder
ConcreteBuilderConcreteProduct
AbstractBuilder getInstance()buildPart1()buildPart2()
Product getProduct()
Prototype
● Создание объектов путем копирования прототипов
Client
<<interface>> Cloneable
<<interface>> Proto
Prototype
clone()
clone()
Singleton
● Единственный экземпляр класса
● private конструктор
● public метод getInstance()
Adapter
● Адаптирует произвольный класс для вызова через необходимый клиенту интерфейс
Client <<interface>>Target
method()
Adapter
method()
AnyClass
other()
Bridge
● Связывает иерархию абстракций и иерархию реализаций
Abstraction
Special
method()
method1()
AbstractionImpl
other()
SpecialImpl
other1()
Impl1
Impl2
Spec1
Spec2
Composite
● Для построения иерархических структур
<<interface>> Component
AbstractComponent Composite
SimpleComponent
add(Component)remove(Component)
Component[] getChildren()
Decorator
● Добавляет объекту функциональность динамически
<<interface>> Service
Decorated Decorator
Dec1 Dec2
Facade
● Предоставляет простой доступ к сложным подсистемам
FacadeClient
Flyweight
● Для поддержки множества мелких объектов, которые образуют группы с одинаковым состоянием
AbstractFlyweight
SharedFlyweight UnsharedFlyweightFlyweightFactory
Client
Proxy
● Замещает объект, создание которого требует времени, создавая его только в случае необходимости
SlowServiceServiceProxy
<<interface>>ServiceClient
Chain of Responsibility
● Передача запроса по цепочке обработчиков
Client Handler
Hand1 Hand2
Command
● Управление командами
Invoker
Receiver
action()cancel()
<<interface>> Command
ConcreteCommand
execute()undo()
execute()undo()
Interpreter
● Позволяет управлять поведением с помощью простого языка
Client <<interface>> Expression
Terminal Non-Terminal
Iterator
Client<<interface>> Collection <<interface>> Iterator
ConcreteIteratorConcreteCollection
hasNext()next()
hasNext()next()
● Последовательный доступ к элементам коллекции
Mediator
● Класс-посредник для управления изменением состояния других объектов
<<interface>> Mediator <<interface>> Colleague
Mediator
C1
C2
Memento
● Хранение и восстановление состояния объекта
Caretaker
<<interface>> Memento
<<static inner>> Mem Originator
Memento createMemento()setMemento(Memento)
Observer
● Оповещение объектов об изменении состояния
<<interface>> Observer<<interface>> Observable
ConcreteObservableConcreteObserveer
attach(Observer)detach(Observer)
update()
State
● Изменяет поведение объекта в зависимости от состояния
Context State
S1 S2
State currentState
Strategy
● Выбор одного из алгоритмов, реализованных в классе
Context Strategy
S1 S2
State currentState
Template Method
● Позволяет реализовать часть поведения в базовом классе, остальное реализуется в подклассах
Abstract Class
template()operation1()operation2()
Concrete Class
operation1()operation2()
Visitor
● Позволяет сгруппировать операции, выполняемые над структурой объектов
Client
<interface>> Visitor
visitElementA(ElementA)visitElementB(ElementB)
Vis1 Vis2
ObjStructure Element
ElementA ElementB
JDBC
JDBC
● JDBC — Java DataBase Connectivity
● API для доступа к табличным данным, например к реляционной базе данных
● Пакеты java.sql и javax.sql
● Стандарт взаимодействия с СУБД
● Для разных СУБД используется свой драйвер
304
Процесс взаимодействия
Connection conn = DriverManager.getConnection( "jdbc:driver:database", "s999999", "xxx999");Statement stat = conn.createStatement();ResultSet res = stat.executeQuery( "SELECT id, name FROM people");while (res.next()) { int i = res.getInt("id"); String n = res.getString("name");}stat.close();conn.close();
Класс DriverManager
● Автоматически загружает найденные JDBC-драйверы (начиная с версии JDBC 4.0). Более ранние версии драйверов надо загружать вручную методом Class.forName()
● Connection getConnection● getConnection(String url)
◊ URL = jdbc:protocol:host:port:dbname
● getConnection(String url, Properties props)
◊ Properties props = new Properties();◊ props.put("user", "s999999");◊ props.put("passwd", "xxx999");
● getConnection(Stiring url, String username, String passwd)
Интерфейс Connection
● Представляет из себя абстракцию соединения (сессия)
● методы:
● Statement createStatement()● интерфейс Statement — для статических запросов без
параметров
● PreparedStatement prepareStatement(String sql)● PreparedStatement — для изменяемых запросов с параметрами
● CallableStatement prepareCall(String sql)● CallableStatement — для выполнения хранимых процедур
Методы execute...()
● ResultSet executeQuery(String sql) — для исполнения команды SELECT. Возвращает ResultSet
● int executeUpdate(String sql) — для выполнения запросов INSERT, UPDATE, DELETE — возвращает количество измененных строк. Для команд DDL возвращает 0
● boolean execute(String sql) — для выполнения любых запросов. Возвращает true, если в результате получился ResultSet и надо будет вызывать метод getResultSet() или false, если в результате — updateCount
Транзакции
● setAutoCommit(false)
● addBatch(String sql)
● clearBatch()
● executeBatch()
● commit()
● rollback()
● setSavePoint(String)
● releaseSavePoint(Savepoint)
Получение результатов запроса
● ResultSet
● createStatement(sql,
● int resultSetType, ● TYPE_FORWARD_ONLY
● TYPE_SCROLL_INSENSITIVE
● TYPE_SCROLL_SENSITIVE
● int resultSetConcurrency,● CONCUR_READ_ONLY
● CONCUR_UPDATABLE
● int resultSetHoldability● HOLD_CURSORS_OVER_COMMIT
● CLOSE_CURSORS_AT_COMMIT
Интерфейс ResultSet
● while (rs.next()) {
● String name = rs.getString(1);
● int id = rs.getInt("id");
● }
● next() / previous()
● insertRow() / updateRow() / deleteRow()
● updateString(), updateInt()
Метаданные
● ResultSetMetaData ResultSet.getMetaData()● getTableName()
● getColumnCount()
● getColumnName(int n)
● getColumnType(int n)
● DatabaseMetaData Connection.getMetaData()● getCatalogs()
● getTables()
● getSchemas()
Интерфейс DataSource
● javax.sql.*
● Новый способ получения соединения
● Может работать при помощи JNDI (Java Naming Directory Interface)
● Реализация зависит от СУБД
Простой источник данных
● org.postgresql.ds.PGSimpleDataSource
● PGSimpleDataSource ds = new PGSimpleDataSource()
● ds.setServeerName("helios.cs.ifmo.ru")
● ds.setDatabaseName("ucheb");
Регистрация в JNDI
● javax.naming.Context ctx = new InitialContext();
● ctx.bind("jdbc/testDB", ds);
● Context ctx = new InitialContext();
● DataSource ds = (DataSource)ctx.lookup("jdbc/testDB");
Другие виды DataSource
● ConnectionPoolDataSource● pc = getPooledConnection();
● Connection c = pc.getConnection()
Интерфейс RowSet
● javax.rowset.*
● RowSet extends ResultSet
● setUrl(), setUsername(), setPassword(), setCommand("Select * from ...");
● execute()
● next()
● getXXX()
Потомки RowSet
● JdbcRowSet — простая реализация RowSet
● CachedRowSet — позволяет не поддерживать постоянно соединение с базой. Полученный результат кэшируется.
● WebRowSet — позволяет сохранять данные в XML
● FilteredRowSet — позволяет применять фильтры к результату
318
l10n и i18n
319
Локализация и интернационализация
● Локализация — адаптация программных продуктов для определенной местности
● Перевод текста
● Использование соответствующих форматов данных
● Замена звуковой и визуальной информации
● localization = l10n
● Интернационализация — проектирование программ таким образом, чтобы их локализация была возможна без конструктивных изменений
● выделение текстовых данных из кода
● отображение данных с учетом местных форматов
● internationalization = i18n
320
Локаль
● Локаль — совокупность характеристик, определяющих географический, политический или культурный регион
● Класс java.util.Locale
● Элементы локали:● язык — 2 строчные буквы (иногда 3) (ru)
● страна (регион) — 2 заглавные буквы (RU) или 3 цифры
● вариант (например, кодировка для русской локали)
● письменность — 4 буквы, первая заглавная (Cyrl)
● расширение
321
Создание локали
● Конструкторы класса Locale● new Locale(String lang)
● new Locale(String lang, String country)
● new Locale(String lang, String country, String variant)
● Класс Locale.Builder● new Locale.Builder().setLanguage("ru").setRegion("RU").build()
● Метод forLanguageTag()● Locale.forLanguageTag("ru-RU);
● Константы класса Locale● Locale.FRENCH
● для русского константы нет
322
Методы для работы с локалью
● Получение списка локалей и локали по умолчанию● static Locale[] getAvailableLocales()
● static Locale getDefault()
● Преобразование в строку● String toString() // ru_RU
● String getDisplayName() // Russian (Russia)
● Класс LanguageRange — набор языков● *, en-*, *-CA
● List<Locale> filter(List<LanguageRange>, Collection<Locale>)
● Locale.lookup((List<LanguageRange>, Collection<Locale>)
● List<LanguageRange> - осортированный по убыванию
323
Управление ресурсами
● Класс ResourceBundle
● Набор ресурсов вида "ключ-значение"
Locale loc = Locale.US; // Locale.getDefault() = ru_RU;
ResourceBundle rb = ResourceBundle.getBundle("GuiLabels", loc);
1) GuiLabels_en_US
2) GuiLabels_en
3) GuiLabels_ru_RU
4) GuiLabels_ru
5) GuiLabels
● MissingResourceException
324
Ресурсы в виде свойств - PropertyResourceBundle
● GuiLabels_en.properties GuiLabels_ru_properties
s1 = Yes s1 = Да
s2 = No s2 = Нет
ResourceBundle r = ResourceBundle.getBundle("GuiLabels");
JButton b1 = new JButton(r.getString("s1");
JButton b2 = new JButton(r.getString("s2");
● + отдельные текстовые файлы
● - только String
● Кодировка ISO-8859-1 — необходима обработка с помощью native2ascii
325
Ресурсы в виде списка - ListResourceBundle
public class GuiLabels_en extends ListResourceBundle {
public Object[][] getContents() { return contents; }
private Object[][] contents = { {"s1", "Yes"}, {"s2", "No"} };
}
public class GuiLabels_ru extends ListResourceBundle {
public Object[][] getContents() { return contents; }
private Object[][] contents = { {"s1", "Да"}, {"s2", "Нет"} };
}
ResourceBundle r = ResourceBundle.getBundle("GuiLabels");
JButton b1 = new JButton(r.getString("s1");
JButton b2 = new JButton(r.getString("s2");● + любые типы объектов
● - нужна компиляция файлов
326
Форматирование числовых данных
● Класс NumberFormat — абстрактный● NumberFormat nf = NumberFormat.getNumberInstance()
● NumberFormat cf = NumberFormat.getCurrencyInstance()
● NumberFormat pf = NumberFormat.getPercentInstance()
● nf.format(new Float(999.8));
● Класс DecimalFormat● df = (DecimalFormat) nf;
● df.applyPattern("##,#0.00");
● df.format(new Float(888.7));
● Класс DecimalFormatSymbols● DecimalFormatSymbols ds = new DecimalFormatSymbols();
● ds.setDecimalSeparator('=');
● df.setDecimalFormatSymbols(ds);
● df.format(new Float(777.6));
327
Символы шаблона
0 — цифра, 0 отображается
# — цифра, 0 не отображается
. — разделитель десятичной дроби
, — разделитель групп разрядов
E — разделитель мантиссы и порядка
- — знак минус
; — разделитель подшаблонов
% — умножить на 100 и отобразить как процент
‰ — умножить на 100 и отобразить как промилле
¤ — символ валюты
328
Форматирование даты и времени
● Класс DateFormat — абстрактный● DateFormat df = DateFormat.getDateInstance(DateFormat.FULL)
● DateFormat tf = DateFormat.getTimeInstance(DateFormat.LONG)
● DateFormat dtf = DateFormat.getDateTimeInstance(DateFormat.SHORT)
● df.format(new Date());
● Класс SimpleDateFormat● sdf = (SimpleDateFormat) df;
● sdf.applyPattern("yyyy-MM-dd");
● sdf.format(new Date());
● Класс DateFormatSymbols● DateFormatSymbols ds = new DateFormatSymbols();
● ds.setShortWeekdays("пнд","втр","срд","чтв","птн","сбт","вск");
● sdf.setDateFormatSymbols(ds);
● sdf.format(new Date());
329
Символы шаблона
Более 4 символов — полный формат, 3 — сокращенный, 2 - число
G — эра
y — год
M — месяц после числа
L — месяц (название)
d — число
E — название дня недели
H — часы
m — минуты
s — секунды
S — миллисекунды
z — временная зона
330
Форматирование сообщений
● Класс MessageFormat● 9 марта 2016 в 1:58 произойдет полное солнечное затмение.
● Total solar eclipse will happen at 1:58 on March 9, 2016.
Solar_en.propertiesmsg = {0} solar eclipse will be at {1,time,short} on {1,date,short}.full = Totalpart = PartialSolar_ru.properties{1,date,short} в {1,time,short} будет {0} солнечное затмениеfull = полноеpart = частное
ResourceBundle r = ResourceBundle.getBundle("Solar");MessageFormat mf = new MessageFormat(r.getString("msg");Calendar x = new Calendar(); x.set(2016,3,9,1,58,0);Object[] args = {r.getString("full", x.getTime()};mf.format(args);
331
Формат с выбором
● Класс ChoiceFormat extends NumberFormat● 0 friends like it
● 1 friend likes it
● 1000 friends like it
Like_en.propertiesmsg = {0} itone = {0,number} friend likesmany = {0,number} friends like
ResourceBundle r = ResourceBundle.getBundle("Like");MessageFormat mf = new MessageFormat(r.getString("msg");double[] lims = { 0, 1, 2 };String o = r.getString("one");String m = r.getString("many");String[] msgs = { m, o, m };ChoiceFormat cf = new ChoiceFormat(lims, msgs);mf.setFormatByArguments(0, cf);Object[] args = { new Integer(15) };mf.format(args);
332
Сравнение строк
● Класс Collator - абстрактный
● Collator getInstance()
● int compare()
List<String> lst = Arrays.asList({"Fluor", "Chlor","Brom","Jod"});
Collator c1 = Collator.getInstance(Locale.EN);
Collator c2 = Collator.getInstance(new Locale("cz","CZ");
lst.sort(c1); // Brom, Chlor, Flour, Jod
lst.sort(c2); // Brom, Fluor, Chlor, Jod
// A, Á, B, C, Č, D, Ď, E, É, Ě, F, G, H, Ch, I, Í, J, K, L, M, N,
// Ň, O, Ó, P, Q, R, Ř, S, Š, T, Ť, U, Ú, Ů, V, W, X, Y, Ý, Z, Ž
● RuleBasedCollator
333
Разбор текста
● Класс BreakIterator — поиск границ
● Методы● getCharacterInstance()
● getWordInstance()
● getSentenceInstance()
● getLineInstance()
● int first()
● int last()
● int next()
● int previous()
● int following(int offset)
● int preceding(int offset)
● BreakIterator.DONE
334
Дата и время
335
Использование даты и времени
● Дата и время — 2 варианта представления:● Человеческое время — часы, минуты, дни, недели, месяцы
● Машинное время — миллисекунды от нулевой точки отсчета
◊ 1 января 1970 года, 00:00:00
336
Традиционные классы. Date
● Date● в версии 1.0 — единственный класс даты
● человеческое и машинное представление
● форматирование даты
● версия 1.1 — Date — момент времени
● почти все методы объявлены deprecated
● Конструкторы● Date
● Date(long)
● Методы● long getTime()
● boolean after(Date)
● boolean before(Date)
337
TimeZone
● Временная зона — смещение от стандартного:
● до 1972 года - Гринвич (GMT)
● после 1972 — UTC — всемирное координированное
● Методы● getDefault()
● getAvailableIDs()
● getRawOffset() - смещение без учета летнего времени
● getOffset(long date) — с учетом летнего времени
● Класс SimpleTimeZone — реализованный потомок
338
Calendar
● Абстрактный класс — преобразование из машинных в человеческие единицы
● Calendar getInstance()
● add(int field, int amount);
● roll(int field, int amount);
● set(int field, int value);
● Date getTime()
● setTime(Date)
● реализованный класс GregorianCalendar● сочетает 2 календаря (григорианский и юлианский)
339
Новые пакеты
● java.time — основной пакет для работы с датой и временем
● java.time.chrono — календарные системы
● java.time.format — классы для форматирования
● java.time.temporal — преобразования времени и вычисления
● java.time.zone — работа с поясным временем
● Все классы — неизменяемые, потокобезопасные
●
340
Соглашения по именам методов
● Статические● of — создает экземпляр на основе входных параметров
● from — конвертирует экземпляр из другого типа
● parse — создает экземпляр из строкового представления
● Методы экземпляра● format — форматирует объект в строку
● get — возвращает частичное состояние объекта
● is — проверяет параметр объекта
● with — возвращает копию объекта с одним измененным элементом
● plus — возвращает копию объекта с добавленным временем
● minus — возвращает копию объекта с убавленным временем
● to — преобразует объект в другой тип
● at — комбинирует объект с другим
341
Перечисляемые типы — дни недели и месяцы
● enum DayOfWeek (1 (MONDAY) — 7 (SUNDAY))
● enum Month (1 (JANUARY) — 12 (DECEMBER))
● метод getDisplayName(style, locale)
● стиль — FULL, NARROW, SHORT / STANDALONE
342
Классы для представления даты и времени
год месяц день час минута секунда нано
Year x
YearMonth x x
MonthDay x x
LocalDate x x x
LocalTime x x x x
LocalDateTime x x x x x x x
.of(year,month,day,hour,min,sec,nano)
.now()
YearMonth Year.atMonth(Month)LocalDate MonthDay.atYear(Year)LocalDate YearMonth.atDay(day)LocalDate Year.atMonthDay(MonthDay)LocalDateTime LocalDate.atTime(LocalTime)LocalDateTime LocalTime.atDate(LocalDate)
.get .with .plus .minus
.getNano() .plusNanos(nano)
.getSecond() .plusSeconds(sec)
.getMinute() .plusMinutes(min)
.getHour() .plusHours(hour)
.getDayOfMonth() .plusDays(day)
.getDayOfWeek() .plusWeeks(week)
.getMonth() .plusMonths(month)
.getYear() .plusYears(year)
343
Классы для представления временной зоны
● ZoneId — идентификатор зоны● Europe/Moscow
● ZoneOffset — разница со стандартным временем● UTC+01:00, GMT-2
● OffsetTime = LocalTime + ZoneOffset
● OffsetDateTime = LocalDateTime + ZoneOffset
● ZonedDateTime = LocalDateTime + ZoneId● использует java.time.zone.ZoneRules
344
Момент времени
● Класс Instant
● now()
● plusNanos()
● plusMillis()
● plusSeconds()
● minusNanos()
● minusMillis()
● minusSeconds()
345
Разбор и форматирование
● java.time.format.DateTimeFormatter● формат можно выбрать из констант:
◊ BASIC_ISO_DATE◊ ISO_DATE/TIME/DATETIME◊ ISO_LOCAL_DATE/TIME/DATETIME◊ ISO_OFFSET_DATE/TIME/DATETIME◊ ISO_ZONED_DATETIME◊ ISO_INSTANT
● задать шаблон
◊ ofPattern()
● методы format() и parse()
346
Периоды даты и времени
● Duration — продолжительность в часах и менее● toNanos(), toMillis(), toSeconds(), toMinutes(), toHours(), toDays()
● Period — период в днях и более● getDays(), getMonths(), getYears()
● .between()
● .plus
● .minus
347
Взаимодействие старых и новых классов
Соответствия: ● Date — Instant
● GregorianCalendar — ZonedDateTime
● TimeZone — ZoneId, ZoneOffset
● Методы:● Calendar.toInstant()
● GregorianCalendar.toZonedDateTime()
● GregorianCalendar.fromZonedDateTime()
● Date.fromInstant()
● Date.toInstant()
● TimeZone.toZoneId()