Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Как создать jar-архив:
- jar cfe hw.jar (имя) HelloWorld (имя главного класса) HelloWorld.class (перечисляем все классы, которые войдут в архив)
- Просмотр содержимого : jar tf hw.jar
- Распаковка : jar xf hw.jar
- j
- Примитивные типы:
- boolean
- char
- byte, short, int, long
- float, double
- переменная примитивного типа - ячейка памяти, в которой хранится значение переменной.
- примитивные типы передаются по значению (когда делаем b = a, то создаётся копия значения а в др.ячейке)
- boolean:
- && : если левый операнд - false -> правый не вычисляется (аналогично для ||)
- & и | реализуют вычисления по полной схеме.
- целочисленные типы:
- все типы имеют фиксированный диапазон под все платформы.
- беззнаковых типов не существует.
- 8-ричная сс: 015 (ведущий ноль)
- 16-ричная сс: префикс 0x
- двоичная сс: префикс 0b
- между цифрами разрешено ставить подчеркивания (10_000)
- если в коде нужно записать число, не влезающее в int, нужно добавить суффикс L
- операторы инкремента и декремента возвращают число (преинкремент вернет после инкремента, пост - до)
- char:
- беззнаковый
- хранит код символа в кодировке Unicode
- float, double:
- вещественные литералы по умолчанию имеют тип double.
- от вещественных чисел можно брать остаток от деления
- +- 1.0 / 0.0 = +- inf (корректное значение, ошибки не будет)
- 0.0 / 0.0 = nan
- nan != nan
- Классы-обёртки:
- Класс с единственным полем value соответствующего типа.
- Зачем нужны?
- -хранить в коллекциях (не поддерживают примитивные типы)
- -в программе нужно указать отсутствие значения (null)
- boxing : Integer b = Integer.valueOf(a); //int a;
- unboxing : int a = b.intValue();
- неявное приведение : Integer a = 10; - медленнее, чем примитив
- Ссылочные типы:
- все остальные типы в Java - сссылочные.
- переменная ссылочного типа : ячейка памяти, содержащая ссылку на участок памяти, представляющую собой объект.
- объект лежит в произвольном месте памяти.
- в отличие от указателей в С со ссылками нельзя производить какую-либо арифметику.
- объявление переменной и выделение памяти под объект - 2 независимых действия.
- объект создается оператором new. new вызывает конструктор.
- оператор == сравнивает ссылки!
- для сравнения объектов по содержимому сущ-вует метод equals (не работает для массивов, там тоже сравн. ссылки)
- Массивы :
- int[] a / int a[] - корректно.
- int[] a = new int[100]; //размер массива фиксирован и не может быть изменен.
- при создании массива все эл-ты автоматически инициализируются нулями соответствующего типа.
- инициализация : int[] a = new int[] {1, 2, 3};
- int[] a = {1, 2, 3}; - так тоже можно
- многомерность массивов не совсем честная : это просто массив ссылок, но это позволяет сделать ступенчатые массивы.
- сравнение массивов : Arrays.equals(a, b); - одномерные
- Arrays.deepEquals(a, b); - многомерные
- вывод массива на экран : sout(Arrays.toString(a));
- sout(Arrays.deepToString(a));
- ключевое слово final действует только на ссылку на массив, к элементам не относится
- Строки :
- строка - ссылочный тип, хранящий посл-ность символов произвольной длины
- строка != массив символов, но их можно легко конвертировать : String s = new String(c); //c - array of char;
- строки неизменяемы!!!!! когда объект типа string создан, мы не можем поменять ни один символ.
- любое изменение строки связано с созданием нового объекта
- сравнение без учёта регистра : s1.equalsIgnoreCase(s2);
- Метки :
- -существуют в Java только для операторов break/continue;
- пример :
- out:
- for () {
- for () {
- if () {
- break out;
- }
- }
- }
- Преобразование типов:
- -при приведении более ёмкого целого типа к менее ёмкому старшие разряды отбрасываются.
- -слишком большое по модулю вещественное число при приведении к целому превращается в максимальное по модулю
- представимое целое число того же знака.
- -слишком большое double при приведении к float превращается в inf.
- -автоматическое приведение типов :
- если один из операндов имеет тип double (float -> long), иначе оба приводятся к типу int! // byte c = (byte) a + b;
- ООП :
- package :
- пакет задаёт область видимости класса; др.классы этого же пакета могут обращаться по короткому имени, классы из др пакетов - по полному, или использовать директиву import.
- классы из пакета по умолчанию невозможно использовать из др. пакетов, даже при наличии явного импорта.
- import static - импортировать статические поля и методы.
- никакой подстановки тела импортированных классов (как #include) не происходит.
- example :
- import static java.lang.Math.sqrt;
- //
- sqrt(4);
- Модификаторы доступа :
- public - доступ разрешён отовсюду без ограничений.
- protected - доступ разрешён только для классов-наследников и классов текущего пакета.
- package-private - в пределах пакета.
- private - в пределах класса.
- -отсутствие модификатора = область видимости в пределах пакета (package-private)
- -protected/private не применимы к классам верхнего уровня, можно применять к вложенным классам.
- -в одном файле могут быть объявлены несколько классов, но модификатором public может обладать только один из них.
- его имя должно совпадать с именем файла
- final - от этого класса нельзя наследоваться
- native - реализация данного метода нах-ся в нативном си-шном коде
- Классы:
- Конструктор :
- -создание : модификатор доступа_имя класса
- -если параметр конструктора имеет имя такое же как и поле класса, то нужно использовать this (this.value = value)
- -если в классе не объявлен ни один конструктор, неявно создается конструктор по умолчанию, без параметров.
- -запретить создание класса = сделать конструктор приватным
- -в классе может быть несколько перегруженных конструкторов с разными агрументами, из одного можно вызывать другой
- Поля и методы :
- -final - метод не может быть переопределён в классах-наследниках
- -в классе может быть несколько методов с одинаковыми именами, но разными наборами параметров
- -статические поля и методы существуют независимо от экземлпяров класса и могут вызываться по имени класса
- -статический метод не имеет доступа к this и нестатическим полям и методам
- -static final - константа
- Вложенные классы:
- -если вложенный класс объявлен с модификатором static, то связь с внешним классом теряется
- Перечисления:
- -enum - полноценный ссылочный тип; класс с фиксированным количеством экземпляров
- -значения эквивалентны public static final полям класса
- -в перечислениях можно объявлять поля и методы, конструктор
- -для enum определены методы name() и ordinal(), values()
- Аннотации:
- @Deprecated - класс устарел
- @SuppressWarnings - временно отключает предупреждения компилятора о подозрительных местах в коде
- Наследование:
- -унаследованный класс автоматически получает все поля и методы базового класса
- -при пользовании не важно, объявлено ли поле в классе-наследнике или его родителях
- -в классе-наследнике можно переопределять методы (завести метод с такими же именем и параметрами,
- как в базовом классе). тип возвращаемого значения должен либо совпадать, либо быть подклассом типа, возвращаемого базовым методом, а модификатор доступа либо тем же, либо более открытым. тогда метод наследника заменит собой одноимённый метод базового класса.
- -создание экземпляра класса-наследника вкл. в себя инициализацию базового класса (вызов его конструктора)
- -super обязан идти перед всем кодом в классе
- -можно вызвать метод базового класса при наличии переопределённого метода у наследника :
- public StringBuilder append(String str) {
- super.append(str); //если б тут не было super'а, метод вызывал бы сам себя.
- return this;
- }
- -super можно писать только в классе-наследнике
- -если ничего не сказано про налседование, то подразумевается что он наследуется от java.lang.Object
- -Object - родитель всех ссылочных типов : массивов, перечислений, аннотаций
- -Object содержит методы toString(), equals(), hashCode()
- -реализация метода toString() в классе Object формирует строку вида "имя класса@16-ричный хэш-код"
- -реализация метода equals() в классе Object происходит по ссылке (в наследниках - по содержимому), т.к. на таком абстрактном уровне больше ничего сделать нельзя.
- -реализация метода equals() уровнями ниже :
- приводим классы к одному типу (если один instanceOf другого) и сравниваем по полям
- -если a.equals(b), то a и b одинаковые хэш-коды
- -anObject instanceOf String - является ли объект экземпляром класса String (подклассы тоже считаются)
- -null instanceOf чего угодно - false
- -hashCode() не возвращает адрес объекта!
- -принцип подстановки : если S extends T, то все объекты класса T могут быть заменены на объекты класса S
- Абстрактные классы :
- -если класс объявлен как абстрактный, это значит что нельзя создавать его экземпляры. создать можно только
- экз. класса-наследника, не яв-ся абстрактным
- -в абстрактном классе могут существовать абстрактные методы (без реализации), которые мы не можем реализовать на данной иерархии наследования. все неабстрактные классы-наследники должны реализовать этот метод.
- -наличие неабстрактных методов в абстрактном классе приведёт к ошибке компиляции ???
- Интерфейсы :
- -Интерфейс - альтернатива абстрактному классу, в котором все методы публичные и абстрактные
- -поля в интерфейсе могут быть только публичные статические финальные (константы)
- -в интерфейсе могут быть :
- -публичные статические методы
- -default-методы (можно задать реализацию по умолчанию, если в классе, реализующем интерфейс, метод неопределен)
- -в java можно объявлять классы реализующие произвольное кол-во интерфейсов
- -примеры интерфейсов : -CharSequence (String, StringBuilder : length(), charAt(), subSequence()),
- -Appendable (Stringbuilder : append)
- -Runnable( : Run())
- -Comparator<T>( :Compare())
- -интерфейсы, в которых ровно один абстрактный метод, называются функциональными @FunctionalInterface
- -интерфейсы позволяют писать максимально обобщённый код, допускающий самые разнообразные реализации
- ------------------------------------------------------------------------------
- Исключения:
- Исключения в Java делятся на 3 группы : Error, Exception, Runtime Exception
- Error и его подклассы - ошибки JVM. Их не надо обрабатывать, т.к. помочь виртуальной машине вряд ли удастся
- Runtime Exception - unchecked, их не надо декларировать на уровне метода. Exception - checked.
- В переопределённом методе можно бросать <= исключений, чем в методе-родителе.
- Непроверяемые - NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException (/0)
- Обработка икслючений:
- Выполняется только один первый подходящий блок Catch. Остальные не будут.
- Можно делать : catch (FirstException | SecondException e)
- После try может быть блок finally, который выполнится в любом случае - было исключение или нет.
- В этом блоке обычно занимаются освобождением ресурсов.
- Если в finally случилось исключение, то полетит оно, а предыдущее будет потеряно.
- try with resources : try (InputStream is = new FileInputStream("in.txt"); OutputStream..) { };
- Гарантируется, что в каждом из ресурсов будет вызыван метод close.
- Здесь исключение из close не перебьёт собой исходное исключение, а будет добавлено к нему в кач-ве заглушенного
- Ресурс - любой объект, реализующий интерфейс AutoCloseable
- Доступ к файловой системе:
- -класс File : File file = new File(путь) //объявление
- -путь к файлу можно собирать в программе :
- String dirName = "src";
- String fileName = "Main.java";
- String path = dirName + File.separator /*File.separatohChar*/ + fileName;
- File.separator - подходящий для данной ОС разделитель.
- File.pathSeparator - разделитель путей
- -также задать правильный путь можно с помощью конструктора :
- File file = new File(dirName, fileName); //путь он склеит сам
- -путь может быть абсолютный (относительно корневой директории) и относительный.
- относительный можно превратить в абсолютный с помощью file.getAbsolutePath(); // isAbsolute() - проверка
- file.getAbsoluteFile(); - возвращает экз. класа File
- -из файла можно "вынуть" путь : String path = file.getPath();
- имя : String name = file.getName();
- родительскую директорию : String parent = file.getParent(); //getParentFile() возвр. File
- -file.getCanonicalPath() /*getCanonicalFile()*/- возвращает канонический путь (без '.', ".." и ссылок) сравнить пути = сравнить канонические пути. Данный метод требует обращение к диску, поэтому может кинуть IOException
- -существование объекта File не привязано к сущ-ю объекта или директории на диске. конструктор ничего на диске не создает, поэтому путь может указывать на несуществующие директории
- -file.exists(); - существует ли? file.isFile() / file.isDirectory() - файл или директория?
- -file.length() - длина, file.lastModified() - время посл.изменения (если файлы не сущ. то возвр.0, а не exception)
- -if (file.isDirectory())
- directory.list() /* String[] */ или directory.listFiles() /* File[] */ - содержимое (если несущ - null)
- -boolean success = file.createNewFile(); //создает новый пустой файл, throws IOException (нет прав, не существует директории).
- -File dir = new File("a/b/c/d");
- boolean suc = dir.mkdir(); //создает максимум 1 директорию
- boolean succ = dir.mkdirs();
- -boolean success = file.delete(); - удаляет файл или директорию (только если директория пуста -> приходится писать рекурсивный обход)
- -boolean renameSuc = file.renameTo(targetFile) //принимает File! ; таким образом можно перенести в др. директорию
- Java.nio.file.Path
- Аналог старого File
- Path - строчка, обёрнутая набором методов для синтаксических манипуляций, не привязанная к существованию файла на диске
- Path path = Paths.get(путь) // так получать экземпляр класса
- Files.createDirectory/Files.createDirectories - аналог mkdir(s)
- Ввод/Вывод:
- Потоки байт:
- Ввод:
- java.io.InputStream - абстрактный класс, представляет собой поток байт, откуда можно читать. На этом уровне абстракции мы даже не знаем, откуда читаем
- read() - возвр. следующий байт входного потока и сдвигается дальше. возвр.значение имеет тип int, но фактически считывается только 1 байт. int нужен чтобы обозначить конец потока (-1). Получить байт = явно прикастовать к byte. Бросает IOException.
- read(byte b[]) - читает число байт, равное длине массива и записывает в него. возвр значение - кол-во считанных байт, оно м.б. меньше, чем мы просили (поток закончился / недостаточно данных на данный момент)
- read(byte b[], int off, int len) - начиная с какого и сколько заполнять
- long skip(long n) - сколько байт пропустить. возвращает, сколько байт удалось пропустить
- close() - закрывает поток и освобождает связанные с ним ресурсы
- Вывод:
- java.io.OutputStream
- write(int b) - выводит младшие 8 бит числа b
- write(byte b[]) - выводит массив
- flush() - сбрасывает буфера
- close() - закрывает поток и освобождает связанные с ним ресурсы
- Пример кода для копирования данных из входного потока в выходной:
- int totalBytesWritten = 0;
- byte[] buf = new byte[1024];
- int blockSize;
- while ((blockSize = inputStream.read(buf)) > 0) {
- outputStream.write(buf, 0, blockSize);
- totalBytesWritten += blockSize;
- }
- FileInputStream/FileOutputStream - чтение/запись из файла. В кач-ве параметра конструктора принимают строку или экземпляр класса File. Если на руках экземпляр Path, то можно получить стрим с помощью
- Files.newInputStream(Paths.get("in.txt"));
- Обмен данными по сети:
- Socket - сетевое соединение
- try (Socket socket = new Socket("ya.ru", 80)) {
- OutputStream out = socket.getOutputStream();
- InputStream in = socket.getInputSream();
- }
- ByteArrayInputStream - чтение из массива байт
- Один стрим может быть завёрнут в другой: внутренний занимается реальным вводом/выводом, внешний - его декорирует
- DataOutputStream оборачивает OutputStream и добавляет методы записи примитивных типов : writeInt..
- Аналогично для IS
- Закрытие внешнего стрима закрывает вложенные в него стримы
- DeflaterInputStream/OutputStream - используются для сжатия и распаковки данных "на лету" (по алгоритму Deflate)
- Потоки символов:
- Ввод:
- java.io.Reader
- Устроен аналогично InputStream, только char вместо byte
- Вывод:
- java.io.Writer
- Устроен аналогично OutputStream, есть перегруженные методы для вывода строк
- Можно превратить поток байт в поток символов, завернув его в InputStreamReader/OutputStreamWriter, при этом указав кодировку (правило перевода байтов в символы). Передать ее можно в виде строки с именем или объекта типа Charset (из StandartCharsets или с помощью Charset.forName("имя"))
- Если кодировка не будет указана, то будет использоваться системная кодировка по-умолчанию (Charset.defaultCharset)
- Reader reader = new InputStreamReader(inputStream, "UTF-8");
- FileReader/FileWriter - для работы с файлом. Но они не позволяют явно указать кодировку, поэтому для работы с файлами используются такие конструкции:
- Reader reader = new InputStreamReader(new FileInputStream("in.txt"), StandartCharsets.UTF_8);
- CharArrayReader/StringReader - для чтения из массива или строки (writer аналогично)
- BufferedReader:
- Запоминает считанные символы в буфере
- readLine() считывает строку (символ конца строки не возвращается). Если поток закончился - null
- Files.newBufferedReader(Paths.get("in.txt"), StandartCharsets.UTF_8)
- вместо
- BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("in.txt"), "UTF-8"));
- Files.readAllLines - вернет строки из файла в виде списка
- BufferedWriter:
- Аналогично BufferedReader
- writer.write("123");
- writer.newLine(); // перевод строки
- Форматированный вывод:
- PrintWriter:
- оборачивает Writer
- есть методы print/println, перегруженные для всех примитивных типов, строк, объектов
- есть метод printf (как в С)
- методы не бросают исключений, а устанавливают внутренний флаг ошибки, который можно проверить с помощью checkError()
- PrintStream
- оборачивает OutputStream и сам им является
- Форматированный ввод:
- StreamTokenizer - читает из потока
- StringTokenizer - читает из строки - не очень удобные классы
- Scanner:
- Можно указать шаблон разделителя, который будет использоваться для нарезания входного потока на токены, а так же Locale (запятая как разделитель вещественных чисел)
- Класс System:
- System.in - InputStream
- System.out, System.r - PrintStream
- Generics:
- -параметризация возможна только ссылочным типам TreeNode<String>, TreeNode<Integer>, TreeNode<int[]> - ок
- -класс Optional - объект может быть/ не быть:
- Optional<String> abc = Optional.of("abc");
- abc.ifPresent(System.out::println); <=> if (s != null) sout.. //где s - String
- Optional<String> bar = Optional.empty();
- String value = bar.orElse("bar"); <=> s != null ? s : "bar"
- -статический (нестатический тоже) можно параметризовать отдельно от класс, объявив Generic-параметр после модификатора доступа
- -в отличиие от шаблонов в С++ явная подстановка конкретного типа данных и создание новых классов с ним отсутствует, класс всегда один. В байткоде получается класс, имеющий вместо T тип Object
- -если не указать параметризованный тип, то класс будет принимать и отдавать Object
- -внутри параметризованного класса или метода нельзя создавать экземпляр или массив Т, также неработает проверка instanceof
- -Generics и наследование:
- Экземпляру базового класса можно без приведения присвоить экземпляр производного класса, но
- если они выступают в роли параметров параметризованного класса, так не работает:
- Optional<Integer> optionalInt = Optional.of(1);
- Optional<Number> optionalNumber = optionalInt; //тут будет ошибка
- Иначе можно было бы сделать так:
- optionalNumber.set(new BigDecimal("3.14"));
- В ситуации с массивами так тоже нельзя сделать, будет брошено ArrayStoreException
- Если нужно получить объект откуда-то, то нужно использовать <? extends T>
- Если отдавать - <? super T>
- Когда нам все равно, каким типом параметризован класс, можно написать <?>
- Если мы захотим из такого класса получить значение типа T, оно будет возвращаться как Object
- Методы, принимающие параметр типа Т, нельзя будет вызвать
- Collections:
- -коллекции находятся в пакете Java.util
- -коллекции для многопоточных программ - в Java.util.cuncurrent
- -у каждого класса коллекции есть конструктор, принимающий параметром другую коллекцию
- public interface Collections<E> extends Iterable<E> {
- int size();
- boolean isEmpty();
- boolean contatins(Object o);
- boolean add(E e);
- boolean remove(Object o);
- void clear();
- Iterator<E> iterator();
- }
- Итераторы:
- Java.util.Iterable:
- -hasNext()
- -next() //throws NoSuchElementException
- -remove()
- Если в процессе обхода нужно удалять из коллекции некоторые элементы, то придется использовать итератор явно.
- Попытка вызывать remove() при обходе коллекции бросит java.util.ConcurrentModificationException.
- Не стоит менять коллекции в процессе обхода не через итераторы
- List:
- public interface Lise<E> extends Collection<E> {
- E get(int index);
- E set(int index, E element);
- void add(int index, E element);
- E remove(int index);
- int indexOf(Object o); //returns -1 if not contains
- int lastIndexOf(Object o); //returns -1 if not contains
- List<E> subList(int fromIndex, int toIndex); //изменения одного списка будут видны в другом (не копирование)
- }
- реализации :
- ArrayList<E>
- LinkedList<E> //двусвязный список
- Queue:
- public interface Queue<E> extends Collection<E> {
- boolean add(E e); //throws exception
- boolean offer(E e); //returns false
- E remove(); //throws exception
- E poll(); //returns null
- E element(); //throws exception
- E peek(); //returns null
- }
- Deque:
- public interface Deque<E> extends Queue<E> {
- void addFirst(E e);
- void addLast(E e);
- boolean offerFirst(E e);
- boolean offerLast(E e);
- E removeFirst();
- E removeLast();
- }
- реализации:
- ArrayDeque<E>
- LinkedList<E>
- Set:
- Не добавляет новых методов интерфейса Collection
- Реализация:
- HashSet // Пока объект лежит в HashSet, не должны меняться его поля, меняющие equals() и hashCode()
- LinkedHashSet
- SortedSet:
- public interface SortedSet<E> extends Set<E> {
- SortedSet<E> subSet(E fromElement, E toElement);
- SortedSet<E> headSet(E toElement); //возвращает подмн-во элементов, меньших, чем параметр (изменяется вместе с основным)
- SortedSet<E> tailSet(E fromElement);
- E first();
- E last();
- }
- Реализация:
- TreeSet//Красно-черное дерево
- Элементы должны либо реализовывать Comparable, либо при создании множества в кач-ве параметра конструктора д
- должен передаваться экземпляр Comparator
- Map: //не наследует коллекции, но идеологически к ним относится
- public interface Map<K, V> {
- int size();
- boolean isEmpty();
- boolean containsKey(Object key);
- boolean contatinsValue(Object value);
- V get(Object key);
- V put(K key, V value);
- V remove(Object key);
- void clear();
- Set<K> keySet();
- Collection<V> values();
- Set<Map.Entry<K,V>> entrySet();
- }
- Map не реализует Iterable <=> нельзя обходить итераторами
- map.forEach((k, v) -> System.out.println("%s => %s\n", k, v)); // принимает экземпляр BiConsumer<T, U>
- Реализации:
- HashMap
- LinkedHashMap
- TreeMap
- Устаревшие коллекции:
- Vector
- Stack
- Dictionary
- Hashtable
- Класс Java.util.Collections:
- Collections.shuffle(list);
- Collections.sort(list);
- unmodifiable:
- Set<String> set = Collections.unmodifiableSet(originalSet);
- set.remove("abc"); // throws UnsupportedOperationException
- Возвращает объект-обертку, реализующий тот же интерфейс, что и переданный параметр и предоставляющий доступ на чтение к элементам коллекции, но любая попытка изменить приведет к выбросу исключения
- Collections.toArray()
- Функциональные интерфейсы:
- @FunctionalInterface
- Интерфейс называется функциональным, если в нем ровно один абстрактный метод (default и статические методы, статические поля не в счет)
- Стандартные функциональные интерфейсы находятся в пакете java.util.function, они делятся на 5 семейств
- Consumers:
- -принимают значения, но ничего не возвр. взамен
- public interface Consumer<T> {
- void accept(T t);
- }
- -существуют также IntConsumer, DoubleConsumer... (т.к. нельзя параметризовывать примитивы)
- -можно скомбинировать с помощью метода andThen, compose (разный порядок применения)
- Suppliers:
- -не принимают ничего в кач-ве параметра, а просто возвр. какое-то значение
- public interface Supplier<T> {
- T get();
- }
- Predicates:
- -их метод принимает значние какого-то типа, возвращает булевское значение
- public interface Predicate<T> {
- boolean test(T t);
- }
- имеет статические методы negate, and
- Functions:
- -принимает аргумент и возвр.элемент какого-то типа
- public interface Function<T, R> {
- R apply(T t);
- }
- Operators:
- -частный случай функций (на входе и на выходе значения одного и того же типа)
- public interface UnaryOperator<T> extends Function<T, T> {
- }
- Лямбда-выражения:
- Компилятор не требует повторять типы параметров, т.к. он их знает
- IntUnaryOperation square = x -> {
- return x * x;
- }
- Внутри лямбды можно обращаться к полям того класса, внутри которого была объявлена лямбда, к переменным, объявленным внутри метода, где была объявлена лямбда (но значния им должны быть присвоены ровно 1 раз до создания лямбды, после чего меняться они уже не могут)
- trick:
- int[] counter = new int[] {0};
- IntSupplier sequence = () -> counter[0]++; //ссылка яв-ся эффективно финальной, содержимое - нет
- Функциональные интерфейсы также можно инстанцировать с помощью ссылки на метод:
- ToIntFunction<String> intParser = Integer::parseInt
- Когда ссылаяемся на статический метод : classanem :: methodname
- На нестатический : имяэкземпляра::имя метода
- Можно также ссылаться на конструктор:
- IntFunction<String[]> arrayAllocator = String[]::new
- Comparator<Double> absoluteValueComparator = Comparator.comparing(Math::abs, Double::compare);
- Streams:
- -Stream - посл-ность элементов, потенциально бесконечная
- Многопоточность:
- Все, что находится в методе main, выполняется в main-потоке, все остальные - отпочковываются от него
- В Java многопоточность представлена в виде виртуальной параллельности (процессор быстро переключается между процессами)
- Java пытается распределить потоки между ядрами процессора
- Основная цель многопоточного программирования - не ускорить работу программы, а реализовать какой-то функционал (к примеру, параллельное обслуживание сервером нескольких клиентов)
- Чтобы создать свой поток, нужно отнаследоваться от java.lang.Thread
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement