API. Основные классыšонспект_лекций_2.pdf52 java.io.InputStream...

Preview:

Citation preview

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()

Recommended