Java for Beginner
672 subscribers
541 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Уважаемые подписчики!

В воскресение, в 16:00 по МСК, мы вновь соберемся для онлайн встречи и будем рассматривать последние 4 поведенческих паттерна.
Кроме того, хотелось бы обсудить множество возникающих у Вас вопросов о формате подачи материала, рассматриваемых тем и будущего канала.


Хотелось бы услышать мнение лично от Вас!
Ждем
всех, хотя бы на несколько минут!

Ну или как минимум, напишите в комментах, почему не можете)))
Всем доброго субботнего утра! 🔆

У кого какие планы на сегодня?
Родятся ли сегодня новые pet-проекты?)))


Напоминаю, что у нас есть чат, где можно без проблем что-то спросить или просто поболтать)
https://t.me/Java_Beginner_chat

Пишите если есть вопросы!

И кроме этого, всем и каждому, замечательных выходных! 👍
Мой настольный пенал🤪😂

https://t.me/Java_for_beginner_dev

#Mems
Оглавление обучающих постов часть 1.

История и особенности языка Java
Основы синтаксиса Java
Объявление переменных
Операнды cравнения в Java
Логические операторы
Управляющие конструкции
Циклы
Массивы в Java
Массивы: Обход и основные операции
Введение в ООП и основы классов и объектов
Классы и объекты
Поля и методы класса. Конструкторы
Методы класса
Конструкторы
Статические и блоки инициализации
Инкапсуляция и модификаторы доступа
Абстракция и примеры применения
Наследование
Переопределение методов
Полиморфизм
Абстрактные классы и методы
Интерфейсы
Различия между абстрактными классами и интерфейсами
Перегрузка метода
Пакеты и импорт
Основные принципы организации классов и пакетов
Исключения: Основы
Обработка исключений
Создание собственных исключений
Вложенные и множественные catch блоки
Строки: Основные операции
Класс String и его методы
StringBuilder и StringBuffer
Разница между String, StringBuilder и StringBuffer
Collections, особенности и внутреннее устройство
Коллекции
Arrays, особенности и внутреннее устройство
List, ArrayList, LinkedList
Set, HashSet, TreeSet
Map, HashMap, TreeMap
Введение в I/O (Input/Output)
Классы File и Path
Чтение и запись файлов: FileReader, FileWriter
Буферизованные потоки: BufferedReader, BufferedWriter
Работа с байтовыми потоками: InputStream, OutputStream
Работа с буферизованными байтовыми потоками: BufferedInputStream, BufferedOutputStream
Объектные потоки: ObjectInputStream, ObjectOutputStream
Сериализация и десериализация объектов
Классы-обёртки (Wrapper classes): Integer, Double
Автоупаковка (Autoboxing) и распаковка (Unboxing)
Класс Object и его значение в Java
Другие методы класса Object
Операторы присваивания, инкремента-декремента в Java
Введение в Queue
Введение в Stack
Дженерики
Продвинутые возможности дженериков
Внутренние классы
Статические вложенные классы и примеры использования внутренних классов
Лямбда-выражения
Применение лямбда-выражений в коллекциях и Stream API
Введение в Stream API и основные методы создания стримов
Терминальные методы Stream API
Многопоточность
Использование synchronized в многопоточности
Условные переменные
Многопоточность в Java: wait и notify
Продвинутые аспекты wait и notify
Асинхронизм и Future в Java
CompletableFuture в Java
Комбинирование CompletableFuture
Многопоточность в Java: volatile и Immutable Classes
Многопоточность в Java: Deadlock
Многопоточность в Java: Пул потоков
Многопоточность в Java: ExecutorService
Concurrency
Продвинутые методы ConcurrentHashMap

#Contents
Java for Beginner pinned «Оглавление обучающих постов часть 1. История и особенности языка Java Основы синтаксиса Java Объявление переменных Операнды cравнения в Java Логические операторы Управляющие конструкции Циклы Массивы в Java Массивы: Обход и основные операции Введение в ООП…»
This media is not supported in your browser
VIEW IN TELEGRAM
Уважаемые подписчики!

Напоминаю, что сегодня в 16:00 по МСК, мы вновь соберемся на онлайн встречу и будем рассматривать последние 4 поведенческих паттерна.

Кроме того, хотелось бы обсудить множество возникающих у Вас вопросов о формате подачи материала, рассматриваемых тем и будущего канала.


Хотелось бы собрать как можно больше народу и услышать мнение каждого!🫡

Жду
всех, хотя бы на несколько минут!
Запись нашей вчерашней встречи -
YOUTUBE
RUTUBE

Спасибо тем кто смог прийти, за участие, вопросы и подсказки! Оценил!

Жаль, что все таки для обсуждения пришло не так много участников как хотелось. 😐

На встрече, мы рассмотрели на примерах последние из поведенческих паттернов проектирования:
- Состояние (State)
- Стратегия (Strategy)
- Шаблонный метод (Template Method)
- Посетитель (Visitor)


Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!

Гит репозиторий с результатом - https://github.com/Oleborn/PatternsOfCoding

Всем доброго утра и легкой рабочей недели! 🫡✌️
Встреча_в_Телемосте_25_08_24_20_02_39_—_запись.webm
142.1 MB
Для тех кто не смог победить блокировку Youtube и не желает заходить в Rutube выкладываю видео тут!

Смотрите на здоровье) 🫡

#online_meeting
BitSet, особенности и внутреннее устройство

BitSet — это класс в Java, который представляет собой массив битов с возможностью их динамического увеличения. Он используется для эффективного хранения и манипулирования наборами булевых значений (битов), где каждый бит может быть true (1) или false (0). BitSet принадлежит к пакету java.util и является полезным инструментом для выполнения операций на уровне битов, таких как поиск битовых масок, управление множествами, или работа с флагами.

Особенности BitSet

Эффективное использование памяти:
BitSet предназначен для экономии памяти. В отличие от массивов типа boolean[], где каждый элемент занимает 1 байт, BitSet использует один бит на каждое значение, что значительно снижает объем памяти, требуемой для хранения большого количества булевых значений.

Динамическое расширение:
BitSet динамически изменяет размер своего внутреннего хранилища по мере добавления или изменения значений. Это позволяет работать с большими наборами битов без необходимости заранее задавать их размер.

Быстрые битовые операции:
BitSet предоставляет быстрые методы для выполнения битовых операций, таких как AND, OR, XOR, и NOT. Эти операции применяются ко всему набору битов, что делает BitSet мощным инструментом для задач, требующих обработки множества булевых значений.

Легкость использования:
BitSet предоставляет удобные методы для установки, сброса, проверки и изменения битов по их индексам. Это упрощает работу с булевыми массивами и делает код более читаемым.
Внутреннее устройство BitSet

BitSet внутри представляет собой массив типа long[], где каждый элемент массива хранит 64 бита. Это позволяет хранить биты компактно и выполнять операции на уровне битов очень быстро, используя встроенные в процессор операции.

Основная структура данных:

Основой BitSet является массив long[]. Каждый элемент этого массива представляет собой 64 бита, которые могут быть установлены в 0 или 1.
public class BitSet implements Cloneable, Serializable {
private long[] words;
private int wordsInUse = 0;
// другие поля и методы...
}
Массив words динамически расширяется по мере необходимости. Параметр wordsInUse отслеживает количество используемых элементов в массиве.


Динамическое расширение массива:

Когда в BitSet устанавливается бит с индексом, превышающим текущий размер массива words, происходит расширение массива.
private void ensureCapacity(int wordsRequired) {
if (words.length < wordsRequired) {
// логика увеличения размера массива...
}
}
Этот процесс автоматический и управляется самим классом BitSet, что позволяет пользователю не беспокоиться о ручном управлении памятью.


Битовые операции:

Основные битовые операции (AND, OR, XOR, NOT) выполняются непосредственно на массиве long[], что обеспечивает высокую производительность. Например, операция AND проходит по каждому элементу массива words и применяет побитовую операцию AND:
public void and(BitSet set) {
for (int i = 0; i < wordsInUse; i++) {
words[i] &= set.words[i];
}
recalculateWordsInUse();
}
Это позволяет применять операции ко всему набору битов за один проход, минимизируя затраты времени.


Индексация битов:

Для работы с конкретными битами внутри BitSet, используется индексация. Индекс бита определяет, в каком элементе массива words он находится, и его позицию внутри этого элемента.
private static int wordIndex(int bitIndex) {
return bitIndex >> 6; // Эквивалентно делению на 64
}

public void set(int bitIndex) {
int wordIndex = wordIndex(bitIndex);
words[wordIndex] |= (1L << bitIndex);
}
Здесь метод wordIndex вычисляет индекс элемента массива, в котором находится нужный бит, а побитовый сдвиг устанавливает значение этого бита.


Эффективное использование памяти и производительности:

Благодаря использованию long[], BitSet позволяет эффективно управлять памятью, особенно при работе с большими наборами данных. Битовые операции выполняются быстро, что делает этот класс пригодным для задач, требующих высокой производительности.

#Java #Training #Medium #BitSet
❗️❗️❗️2️⃣0️⃣0️⃣ подписчиков!!! ❗️❗️❗️

Ребят, я не знаю, как и зачем Вы к нам пришли, но по всей видимости Вы что-то ищете и ждете от нашего канала.

Я всеми силами буду стараться это Вам дать, и продолжать обучать и самообучаться Java дальше!🫡


Независимо от всего этого я искренне благодарен всем, кто находится здесь, приходит на встречи, интересуется и пишет комментарии, участвует в обсуждениях в чате!

Спасибо ребят!🤝

Давайте и дальше становиться лучшим пабликом для изучающих Java!💪

Дальше будет интереснее....😏
Что выведет код?

import java.util.BitSet;

public class Main {
public static void main(String[] args) {
BitSet bitset = new BitSet(10);
bitset.set(0);
bitset.set(3);
bitset.set(5);
bitset.set(7);
bitset.flip(0, 6);
bitset.clear(7);

for (int i = 0; i < 10; i++) {
System.out.print(bitset.get(i) ? "1" : "0");
}
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
33%
1101000000
0%
0101010000
33%
0110100000
33%
0110101000
Фронтендеры простите😂😉

https://t.me/Java_for_beginner_dev

#Mems
Основные методы BitSet и их использование

set(int bitIndex) и set(int fromIndex, int toIndex):
Эти методы используются для установки бита или диапазона битов в значение true.
BitSet bitSet = new BitSet();
bitSet.set(2); // Устанавливает бит с индексом 2 в true
bitSet.set(4, 7); // Устанавливает биты с индексами 4, 5 и 6 в true
Если указать диапазон, все биты в этом диапазоне будут установлены в true.


clear(int bitIndex) и clear(int fromIndex, int toIndex):

Эти методы сбрасывают бит или диапазон битов, устанавливая их в false.
bitSet.clear(2); // Сбрасывает бит с индексом 2 в false
bitSet.clear(4, 7); // Сбрасывает биты с индексами 4, 5 и 6 в false
Полезно для обнуления значений или удаления флагов.


get(int bitIndex) и get(int fromIndex, int toIndex):
Эти методы возвращают значение конкретного бита или диапазона битов.
boolean value = bitSet.get(2); // Получает значение бита с индексом 2
BitSet subSet = bitSet.get(4, 7); // Получает поднабор битов с 4 до 6
Возвращаемое значение может быть true или false, а в случае диапазона — новый BitSet.


flip(int bitIndex) и flip(int fromIndex, int toIndex):
Переключает (инвертирует) бит или диапазон битов.
bitSet.flip(2); // Инвертирует бит с индексом 2
bitSet.flip(4, 7); // Инвертирует биты с 4 до 6
Если бит был true, он станет false, и наоборот.


length() и size():
length() возвращает индекс самого старшего бита плюс один, т.е. логическую длину BitSet.
size() возвращает текущий размер внутреннего массива, который является кратным 64.

System.out.println("Length: " + bitSet.length()); // Логическая длина BitSet
System.out.println("Size: " + bitSet.size()); // Текущий размер внутреннего массива
Эти методы полезны для анализа содержимого BitSet и его текущего состояния.


cardinality():
Возвращает количество установленных в true битов (так называемая "мощность" множества).
int numberOfBits = bitSet.cardinality(); // Количество установленных битов
Полезно, когда нужно узнать, сколько значений true содержится в наборе.


and(BitSet set), or(BitSet set), xor(BitSet set):
Методы выполняют побитовые операции AND, OR, XOR над текущим BitSet и заданным BitSet.
BitSet bitSet1 = new BitSet();
bitSet1.set(1);
bitSet1.set(3);

BitSet bitSet2 = new BitSet();
bitSet2.set(2);
bitSet2.set(3);

bitSet1.and(bitSet2); // AND операция между bitSet1 и bitSet2
bitSet1.or(bitSet2); // OR операция между bitSet1 и bitSet2
bitSet1.xor(bitSet2); // XOR операция между bitSet1 и bitSet2
Эти методы полезны для выполнения сложных битовых операций между двумя наборами.


intersects(BitSet set):
Проверяет, есть ли общие установленные биты между двумя BitSet.
boolean hasIntersection = bitSet1.intersects(bitSet2); // true, если есть общие биты
Метод возвращает true, если есть хотя бы один бит, который установлен в true в обоих наборах.


isEmpty():
Проверяет, есть ли хотя бы один установленный бит в BitSet.
boolean isEmpty = bitSet.isEmpty(); // true, если все биты сброшены
Полезно для проверки пустоты множества.


stream():
Позволяет создать поток из установленных битов BitSet. Этот метод особенно полезен для работы с Stream API.
bitSet.stream().forEach(System.out::println); // Выводит индексы установленных битов
Это удобный способ итерирования по установленным битам с использованием функциональных возможностей Java.


Примеры использования

Оптимизация использования памяти:
Если вам нужно хранить большой набор булевых значений, BitSet помогает оптимизировать использование памяти, так как каждый бит занимает всего 1 бит.
BitSet largeSet = new BitSet();
for (int i = 0; i < 1000000; i++) {
if (i % 2 == 0) {
largeSet.set(i);
}
}

System.out.println("Количество установленных битов: " + largeSet.cardinality());
В этом примере BitSet используется для хранения большого количества булевых значений, что значительно экономит память по сравнению с использованием массивов boolean[].


#Java #Training #Medium #BitSet
NavigableSet, особенности и внутреннее устройство

NavigableSet — это один из интерфейсов в Java Collection Framework, который расширяет интерфейс SortedSet. Он предоставляет дополнительные методы для навигации по элементам в наборе на основе их естественного порядка или на основе компаратора, заданного при создании набора. NavigableSet — это специализированная коллекция, которая особенно полезна, когда вам нужно работать с отсортированными наборами данных, и когда важны операции, связанные с поиском ближайших элементов или диапазонов значений.

Особенности NavigableSet

Упорядоченность элементов:
NavigableSet, как и его родительский интерфейс SortedSet, гарантирует, что элементы хранятся в упорядоченном виде. Упорядоченность может быть основана на естественном порядке элементов (если элементы реализуют интерфейс Comparable) или на пользовательском компараторе, переданном в конструктор.

Поддержка поиска ближайших элементов:
NavigableSet предоставляет методы для поиска элементов, которые являются ближайшими к заданному значению. Например, методы ceiling(E e), floor(E e), higher(E e), и lower(E e) позволяют найти наименьший элемент, который больше или равен заданному, наибольший элемент, который меньше или равен заданному, и так далее.

Поддержка поднаборов:
NavigableSet поддерживает создание поднаборов с помощью методов subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive), headSet(E toElement, boolean inclusive), и tailSet(E fromElement, boolean inclusive). Эти методы возвращают новые представления набора, которые включают или исключают определенные диапазоны значений.

Реверсированная версия:
Метод descendingSet() возвращает представление набора в обратном порядке. Это особенно полезно, когда необходимо выполнить операции с набором в порядке, обратном естественному.

Безопасность и неизменяемость:
NavigableSet предоставляет неизменяемые представления поднаборов, что обеспечивает безопасность при многопоточном доступе.

Внутреннее устройство NavigableSet
Хотя интерфейс NavigableSet не определяет, как именно должны быть реализованы коллекции, обычно используется одна из следующих реализаций:

TreeSet:
Самая распространенная реализация NavigableSet в Java — это класс TreeSet. TreeSet основан на структуре данных красно-черного дерева, которая обеспечивает логарифмическое время выполнения основных операций (вставка, удаление, поиск). Поскольку TreeSet является упорядоченной структурой данных, элементы в нем всегда хранятся в отсортированном порядке.

NavigableSet<Integer> navigableSet = new TreeSet<>();
navigableSet.add(5);
navigableSet.add(2);
navigableSet.add(9);

System.out.println(navigableSet); // [2, 5, 9]


ConcurrentSkipListSet:
Еще одна реализация NavigableSet — это ConcurrentSkipListSet. Этот класс основан на структуре данных, называемой "skip list" (список с пропусками). В отличие от TreeSet, который не является потокобезопасным, ConcurrentSkipListSet предоставляет безопасный для многопоточного использования набор с логарифмическим временем доступа. Это делает его идеальным выбором для использования в средах, где требуется потокобезопасность без блокировок.

NavigableSet<String> navigableSet = new ConcurrentSkipListSet<>();
navigableSet.add("banana");
navigableSet.add("apple");
navigableSet.add("cherry");

System.out.println(navigableSet); // [apple, banana, cherry]


NavigableSet будет полезен в следующих сценариях:

Диапазонные запросы:
Если вам нужно работать с подмножествами данных на основе диапазонов, то NavigableSet идеально подходит, так как он позволяет легко извлекать элементы в заданном диапазоне.

Поиск ближайших значений:
Если задача требует частого поиска ближайших значений (например, в географических приложениях для поиска ближайших координат), то NavigableSet предоставляет необходимые методы для таких операций.

Обратный порядок:
Когда нужно получить элементы в порядке, обратном их естественному порядку, метод descendingSet() упрощает эту задачу.

#Java #Training #Medium #NavigableSet
Что выведет код?

import java.util.*;

public class Main {
public static void main(String[] args) {
NavigableSet<Integer> set = new TreeSet<>(Arrays.asList(10, 20, 30, 40, 50));
System.out.println(set.lower(30));
System.out.println(set.floor(30));
System.out.println(set.ceiling(25));
System.out.println(set.higher(50));
}
}


#Tasks
Суровая действительность 🫡

https://t.me/Java_for_beginner_dev

#Mems
Основные методы NavigableSet и примеры использования

Основные методы NavigableSet

E lower(E e)
Возвращает наибольший элемент в наборе, который меньше заданного элемента e. Если такого элемента нет, возвращает null.

NavigableSet<Integer> set = new TreeSet<>(Arrays.asList(1, 2, 3, 4, 5));
System.out.println(set.lower(3)); // Output: 2


E floor(E e)
Возвращает наибольший элемент в наборе, который меньше или равен заданному элементу e. Если такого элемента нет, возвращает null.
System.out.println(set.floor(3)); // Output: 3
System.out.println(set.floor(6)); // Output: 5


E ceiling(E e)
Возвращает наименьший элемент в наборе, который больше или равен заданному элементу e. Если такого элемента нет, возвращает null.
System.out.println(set.ceiling(3)); // Output: 3
System.out.println(set.ceiling(0)); // Output: 1


E higher(E e)
Возвращает наименьший элемент в наборе, который больше заданного элемента e. Если такого элемента нет, возвращает null.
System.out.println(set.higher(3)); // Output: 4
System.out.println(set.higher(5)); // Output: null


E pollFirst() и E pollLast()
Эти методы удаляют и возвращают первый и последний элемент набора соответственно. Если набор пуст, они возвращают null.
NavigableSet<String> set = new TreeSet<>(Arrays.asList("apple", "banana", "cherry"));
System.out.println(set.pollFirst()); // Output: apple
System.out.println(set.pollLast()); // Output: cherry
System.out.println(set); // Output: [banana]


NavigableSet<E> descendingSet()
Возвращает представление текущего набора в обратном порядке. Любые изменения в этом представлении будут отражаться на исходном наборе и наоборот.
NavigableSet<String> set = new TreeSet<>(Arrays.asList("apple", "banana", "cherry"));
NavigableSet<String> descendingSet = set.descendingSet();
System.out.println(descendingSet); // Output: [cherry, banana, apple]


NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)
Возвращает поднабор элементов от fromElement до toElement, при этом можно указать, включать ли эти элементы в поднабор.
NavigableSet<Integer> set = new TreeSet<>(Arrays.asList(1, 2, 3, 4, 5));
NavigableSet<Integer> subSet = set.subSet(2, true, 4, false);
System.out.println(subSet); // Output: [2, 3]


NavigableSet<E> headSet(E toElement, boolean inclusive)
Возвращает поднабор элементов от начала набора до toElement. Можно указать, включать ли элемент toElement в поднабор.
NavigableSet<Integer> headSet = set.headSet(4, true);
System.out.println(headSet); // Output: [1, 2, 3, 4]


NavigableSet<E> tailSet(E fromElement, boolean inclusive)
Возвращает поднабор элементов от fromElement до конца набора. Можно указать, включать ли элемент fromElement в поднабор.
NavigableSet<Integer> tailSet = set.tailSet(3, false);
System.out.println(tailSet); // Output: [4, 5]


Примеры использования NavigableSet

Пример 1: Фильтрация диапазона значений
Предположим, у нас есть набор температур за неделю, и мы хотим получить все температуры в диапазоне от 15 до 25 градусов:
NavigableSet<Integer> temperatures = new TreeSet<>(Arrays.asList(10, 15, 20, 25, 30));
NavigableSet<Integer> comfortableTemperatures = temperatures.subSet(15, true, 25, true);
System.out.println(comfortableTemperatures); // Output: [15, 20, 25]


Пример 2: Поиск ближайшей даты
Допустим, у нас есть набор дат, и мы хотим найти ближайшую дату, которая будет после сегодняшнего дня:
NavigableSet<LocalDate> dates = new TreeSet<>(Arrays.asList(
LocalDate.of(2023, 8, 20),
LocalDate.of(2023, 9, 5),
LocalDate.of(2023, 10, 10)
));

LocalDate today = LocalDate.of(2023, 8, 25);
LocalDate nextDate = dates.ceiling(today);

System.out.println(nextDate); // Output: 2023-09-05


#Java #Training #Medium #NavigableSet