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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Внутреннее устройство и методы Stack

Stack в Java наследует класс Vector, что означает, что он использует динамический массив для хранения своих элементов. Это позволяет Stack автоматически изменять свой размер по мере добавления или удаления элементов.

public class Stack<E> extends Vector<E> {
public Stack() {
}

public E push(E item) {
addElement(item);
return item;
}

public synchronized E pop() {
E obj;
int len = size();

obj = peek();
removeElementAt(len - 1);

return obj;
}

public synchronized E peek() {
int len = size();

if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}

public boolean empty() {
return size() == 0;
}

public synchronized int search(Object o) {
int i = lastIndexOf(o);

if (i >= 0) {
return size() - i;
}
return -1;
}
}


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

push(E item):
Добавляет элемент на вершину стека.
Возвращает добавленный элемент.

Stack<Integer> stack = new Stack<>();
stack.push(10); // Добавляет элемент 10 на вершину стека


pop():
Удаляет и возвращает элемент с вершины стека.
Бросает EmptyStackException, если стек пуст.

int element = stack.pop(); // Удаляет и возвращает элемент 10


peek():
Возвращает элемент с вершины стека без его удаления.
Бросает EmptyStackException, если стек пуст.

int topElement = stack.peek(); // Возвращает элемент 10, но не удаляет его


isEmpty():
Проверяет, пуст ли стек.
Возвращает true, если стек пуст, и false в противном случае.

boolean isEmpty = stack.isEmpty(); // Возвращает false, так как стек не пуст


search(Object o):
Ищет элемент в стеке и возвращает его позицию относительно вершины.
Возвращает -1, если элемент не найден.

int position = stack.search(10); // Возвращает 1, так как элемент 10 на вершине стека


#Java #Training #Medium #Stack
PriorityQueue, принципы работы и внутреннее устройство

PriorityQueue — это класс из пакета java.util, который реализует интерфейс Queue. В отличие от обычной очереди (FIFO), PriorityQueue основана на приоритетах элементов. Приоритет определяется с помощью естественного порядка элементов или через предоставленный компаратор.

import java.util.PriorityQueue;

public class PriorityQueueExample {
public static void main(String[] args) {
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();

priorityQueue.add(4);
priorityQueue.add(1);
priorityQueue.add(3);

while (!priorityQueue.isEmpty()) {
System.out.println(priorityQueue.poll());
}
}
}


В этом примере PriorityQueue автоматически упорядочивает элементы, так что при удалении элементов они извлекаются в порядке возрастания: 1, 3, 4.


Принципы работы PriorityQueue


Естественный порядок или компаратор: Элементы могут упорядочиваться на основе их естественного порядка (если элементы реализуют интерфейс Comparable) или на основе компаратора, предоставленного при создании очереди.
Бинарная куча (Binary Heap): Внутренняя реализация PriorityQueue основана на бинарной куче, которая является частично упорядоченным двоичным деревом. Это позволяет эффективно добавлять элементы и извлекать минимальный элемент.
Время выполнения операций: Основные операции PriorityQueue (вставка, удаление минимального элемента) выполняются за логарифмическое время O(log n), где n — количество элементов в очереди.


Внутреннее устройство PriorityQueue

PriorityQueue использует массив для хранения элементов, которые упорядочиваются в соответствии с правилами бинарной кучи. Дочерние элементы имеют более низкий приоритет по сравнению с родительскими элементами.

public class PriorityQueue<E> extends AbstractQueue<E> implements Serializable {
private static final int DEFAULT_INITIAL_CAPACITY = 11;
private Object[] queue;
private int size;
private final Comparator<? super E> comparator;

public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}

public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
}

public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) {
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.queue = new Object[initialCapacity];
this.comparator = comparator;
}

// Основные методы: add, poll, offer, remove, etc.
}


Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-priorityqueue
https://sky.pro/media/ispolzovanie-priorityqueue-v-java/

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

import java.util.PriorityQueue;

public class PriorityQueueChallenge {
public static void main(String[] args) {
PriorityQueue<String> pq = new PriorityQueue<>();
pq.add("apple");
pq.add("banana");
pq.add("cherry");
pq.add("date");
pq.add("elderberry");

StringBuilder result = new StringBuilder();

while (!pq.isEmpty()) {
String value = pq.poll();
if (value.length() % 2 == 0) {
pq.add(value.substring(1));
} else {
result.append(value.charAt(0));
}
}

System.out.println("Result: " + result);
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
50%
abce
50%
abcde
0%
aaahl
0%
aacde
У него не было шансов👻

https://t.me/Java_for_beginner_dev

#Mems
Завтра в 17:00 по МСК, приглашаем всех на онлайн решение задач с Сodewars!

Решать задачи для Вас и вместе с Вами, будет @Alexander_Gors , за что ему сердечное спасибо! 🤝

Приходите и прокачивайте свои знания!

Ждем всех!
Основные методы PriorityQueue и примеры использования

add(E e):
Добавляет элемент в очередь. Если элемент null, выбрасывает NullPointerException.
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(10);
pq.add(20);
pq.add(15);


offer(E e):
Добавляет элемент в очередь. Возвращает true, если элемент был успешно добавлен, и false в противном случае.
pq.offer(5);


poll():
Возвращает и удаляет элемент с наивысшим приоритетом (минимальный элемент). Возвращает null, если очередь пуста.
Integer top = pq.poll(); // Возвращает 5 и удаляет его из очереди


peek():
Возвращает элемент с наивысшим приоритетом, но не удаляет его. Возвращает null, если очередь пуста.
Integer top = pq.peek(); // Возвращает 10, но не удаляет его


remove(Object o):
Удаляет указанный элемент из очереди, если он присутствует. Возвращает true, если элемент был успешно удален, и false в противном случае.
boolean removed = pq.remove(15); // Удаляет элемент 15


contains(Object o):
Проверяет, присутствует ли указанный элемент в очереди. Возвращает true, если элемент найден, и false в противном случае.
boolean contains = pq.contains(20); // Проверяет наличие элемента 20


size():
Возвращает количество элементов в очереди.
int size = pq.size(); // Возвращает количество элементов в очереди


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

Реализация задачи с приоритетом:
import java.util.PriorityQueue;
import java.util.Comparator;

class Task {
private String name;
private int priority;

public Task(String name, int priority) {
this.name = name;
this.priority = priority;
}

public int getPriority() {
return priority;
}

@Override
public String toString() {
return name + ": " + priority;
}
}

class TaskComparator implements Comparator<Task> {
public int compare(Task t1, Task t2) {
return Integer.compare(t1.getPriority(), t2.getPriority());
}
}

public class TaskScheduler {
public static void main(String[] args) {
PriorityQueue<Task> taskQueue = new PriorityQueue<>(new TaskComparator());

taskQueue.add(new Task("Task 1", 2));
taskQueue.add(new Task("Task 2", 1));
taskQueue.add(new Task("Task 3", 3));

while (!taskQueue.isEmpty()) {
System.out.println(taskQueue.poll());
}
}
}


Использование с Comparator для обратного порядка:
PriorityQueue<Integer> reversePQ = new PriorityQueue<>(Comparator.reverseOrder());

reversePQ.add(10);
reversePQ.add(20);
reversePQ.add(15);

while (!reversePQ.isEmpty()) {
System.out.println(reversePQ.poll());
}


Модель с приоритетом задач на основе времени выполнения:
import java.util.PriorityQueue;

class Job implements Comparable<Job> {
private String jobName;
private int executionTime;

public Job(String jobName, int executionTime) {
this.jobName = jobName;
this.executionTime = executionTime;
}

@Override
public int compareTo(Job other) {
return Integer.compare(this.executionTime, other.executionTime);
}

@Override
public String toString() {
return jobName + ": " + executionTime;
}
}

public class JobScheduler {
public static void main(String[] args) {
PriorityQueue<Job> jobQueue = new PriorityQueue<>();

jobQueue.add(new Job("Job 1", 30));
jobQueue.add(new Job("Job 2", 10));
jobQueue.add(new Job("Job 3", 20));

while (!jobQueue.isEmpty()) {
System.out.println(jobQueue.poll());
}
}
}


#Java #Training #Medium #PriorityQueue
ArrayDeque, внутреннее устройство, особенности и преимущества

ArrayDeque — это реализация двусторонней очереди (deque) на основе массивов, предоставляемая в пакете java.util. Она представляет собой гибкую структуру данных, которая поддерживает вставку и удаление элементов с обеих сторон с амортизированным постоянным временем.

import java.util.ArrayDeque;

public class ArrayDequeExample {
public static void main(String[] args) {
ArrayDeque<Integer> deque = new ArrayDeque<>();

deque.addFirst(1);
deque.addLast(2);
deque.addFirst(3);
deque.addLast(4);

while (!deque.isEmpty()) {
System.out.println(deque.pollFirst());
}
}
}


В этом примере элементы вставляются и извлекаются с обеих сторон очереди, демонстрируя гибкость ArrayDeque.



Внутреннее устройство ArrayDeque

ArrayDeque основана на циклическом массиве, который расширяется по мере необходимости. Это позволяет поддерживать эффективное использование памяти и быструю вставку и удаление элементов с обеих сторон очереди.

public class ArrayDeque<E> extends AbstractCollection<E> implements Deque<E>, Cloneable, Serializable {
private transient E[] elements;
private transient int head;
private transient int tail;

public ArrayDeque() {
elements = (E[]) new Object[16];
}

public ArrayDeque(int initialCapacity) {
elements = (E[]) new Object[initialCapacity];
}

// Основные методы: addFirst, addLast, pollFirst, pollLast, etc.
}


Особенности и преимущества

Циклический массив: Использование циклического массива позволяет избежать необходимости перемещения элементов при вставке и удалении с обеих сторон.
Амортизированное постоянное время: Вставка и удаление элементов с обеих сторон выполняются в амортизированное постоянное время O(1), за исключением случаев расширения массива.
Отсутствие блокировок: ArrayDeque не синхронизирована, что делает её быстрее по сравнению с синхронизированными структурами данных, такими как LinkedBlockingDeque.
Гибкость: Поддержка операций вставки и удаления с обеих сторон очереди предоставляет большую гибкость в использовании.


Преимущества использования ArrayDeque

Производительность: ArrayDeque обеспечивает более высокую производительность по сравнению с LinkedList для операций вставки и удаления элементов с обеих сторон.
Гибкость: Она поддерживает как стековые (push, pop), так и очередные (offer, poll) операции, что делает её универсальной для различных задач.
Эффективное использование памяти: Благодаря циклическому массиву ArrayDeque эффективно использует память, минимизируя количество операций по перемещению элементов.


import java.util.ArrayDeque;

public class ArrayDequeExample {
public static void main(String[] args) {
ArrayDeque<Integer> deque = new ArrayDeque<>();

// Добавление элементов
deque.addFirst(1);
deque.addLast(2);
deque.addFirst(3);
deque.addLast(4);

// Извлечение элементов
System.out.println(deque.pollFirst()); // 3
System.out.println(deque.pollLast()); // 4
System.out.println(deque.pollFirst()); // 1
System.out.println(deque.pollLast()); // 2
}
}

В этом примере демонстрируются основные операции вставки и извлечения элементов с обеих сторон очереди.

Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.baeldung.com/java-array-deque
https://metanit.com/java/tutorial/5.7.php

#Java #Training #Medium #ArrayDeque
Варианты ответа:
Anonymous Quiz
17%
45
17%
10
33%
25
33%
175
Что выведет код?

import java.util.ArrayDeque;

public class ArrayDequeChallenge {
public static void main(String[] args) {
ArrayDeque<Integer> deque = new ArrayDeque<>();
for (int i = 0; i < 10; i++) {
deque.add(i);
}

while (deque.size() > 1) {
deque.removeFirst();
if (deque.size() > 1) {
deque.addLast(deque.removeFirst() + deque.removeLast());
}
}

System.out.println("Result: " + deque.peek());
}
}


#Tasks
Мы научим Вас плохому😂

https://t.me/Java_for_beginner_dev

#Mems
Внимание!

На гитхабе (возможно, где-то еще) стали появляться поддельные версии goodbyedpi.exe с вирусом.
Тот архив с паролем, имейте ввиду. Поддельный goodbyedpi.exe значительно большего веса (в 40+ раз). Оригинальный ~100 КБ, поддельный > 4 МБ.
Благодаря сообществу
ntc.party удалено уже 4 репозитория на гитхабе с поддельным goodbyedpi.exe,
но почти наверняка эти подделки распространились в интернете.


#От_подписчиков
Встреча создана! ☝️

Заходите порешать задачки вместе с нами!⭐️

Ждем всех!
https://telemost.yandex.ru/j/42492956505565
Live stream started
Основные методы ArrayDeque и их применение

Основные методы ArrayDeque:

addFirst(E e):
Добавляет элемент в начало очереди. Если очередь заполнена, увеличивает её размер.
ArrayDeque<Integer> deque = new ArrayDeque<>();
deque.addFirst(10);
deque.addFirst(20);
System.out.println(deque); // [20, 10]


addLast(E e):
Добавляет элемент в конец очереди. Если очередь заполнена, увеличивает её размер.
deque.addLast(30);
System.out.println(deque); // [20, 10, 30]


offerFirst(E e):
Предлагает добавить элемент в начало очереди. Возвращает true, если элемент был добавлен успешно.
deque.offerFirst(40);
System.out.println(deque); // [40, 20, 10, 30]


offerLast(E e):
Предлагает добавить элемент в конец очереди. Возвращает true, если элемент был добавлен успешно.
deque.offerLast(50);
System.out.println(deque); // [40, 20, 10, 30, 50]


pollFirst():
Возвращает и удаляет первый элемент из очереди. Возвращает null, если очередь пуста.
Integer first = deque.pollFirst();
System.out.println(first); // 40
System.out.println(deque); // [20, 10, 30, 50]


pollLast():
Возвращает и удаляет последний элемент из очереди. Возвращает null, если очередь пуста.
Integer last = deque.pollLast();
System.out.println(last); // 50
System.out.println(deque); // [20, 10, 30]


peekFirst():
Возвращает первый элемент из очереди, не удаляя его. Возвращает null, если очередь пуста.
Integer peekFirst = deque.peekFirst();
System.out.println(peekFirst); // 20


peekLast():
Возвращает последний элемент из очереди, не удаляя его. Возвращает null, если очередь пуста.
Integer peekLast = deque.peekLast();
System.out.println(peekLast); // 30


push(E e):
Вставляет элемент на вершину стека. Эквивалентен методу addFirst(E e).
deque.push(60);
System.out.println(deque); // [60, 20, 10, 30]


pop():
Возвращает и удаляет элемент с вершины стека. Эквивалентен методу pollFirst().
Integer pop = deque.pop();
System.out.println(pop); // 60
System.out.println(deque); // [20, 10, 30]



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


Реализация стека с использованием ArrayDeque:
import java.util.ArrayDeque;

public class StackExample {
public static void main(String[] args) {
ArrayDeque<Integer> stack = new ArrayDeque<>();

stack.push(1);
stack.push(2);
stack.push(3);

while (!stack.isEmpty()) {
System.out.println(stack.pop());
}
}
}


Реализация очереди с использованием ArrayDeque:
import java.util.ArrayDeque;

public class QueueExample {
public static void main(String[] args) {
ArrayDeque<Integer> queue = new ArrayDeque<>();

queue.addLast(1);
queue.addLast(2);
queue.addLast(3);

while (!queue.isEmpty()) {
System.out.println(queue.pollFirst());
}
}
}


Реализация двусторонней очереди с использованием ArrayDeque:
import java.util.ArrayDeque;

public class DequeExample {
public static void main(String[] args) {
ArrayDeque<Integer> deque = new ArrayDeque<>();

deque.addFirst(1);
deque.addLast(2);
deque.addFirst(3);
deque.addLast(4);

while (!deque.isEmpty()) {
System.out.println(deque.pollFirst());
}
}
}


#Java #Training #Medium #ArrayDeque
Java for Beginner pinned «Вчера мы провели трансляцию в канале по решению задач с Codewar. Устраивает ли вас такой формат, нужно ли делать запись, для пересмотра?»
LinkedBlockingQueue, отличия от других очередей.

LinkedBlockingQueue — это реализация блокирующей очереди на основе связанного списка, предоставляемая в пакете java.util.concurrent. Она поддерживает опциональную ограниченную емкость и используется для передачи данных между потоками с возможностью блокировки.

Основные отличия от других очередей:

Блокирующая очередь: Ожидает свободного места для добавления или доступного элемента для извлечения.
Основана на связанном списке: В отличие от ArrayBlockingQueue, которая использует массив, LinkedBlockingQueue использует связанный список.
Опциональная ограниченная емкость: Вы можете задать максимальную емкость очереди. По умолчанию емкость не ограничена.


import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueExample {
public static void main(String[] args) {
LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);

try {
queue.put(1);
queue.put(2);
System.out.println(queue.take());
System.out.println(queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


Внутреннее устройство

LinkedBlockingQueue реализует блокирующую очередь с использованием двух внутренних объектов Node, а также использует механизмы блокировок для управления доступом к очереди.

Основные компоненты:

Внутренний класс Node:
Узел, содержащий данные и ссылку на следующий элемент в очереди.
static class Node<E> {
E item;
Node<E> next;

Node(E x) { item = x; }
}


Голова и хвост очереди:

head: Ссылка на первый узел в очереди.
last: Ссылка на последний узел в очереди.

private transient Node<E> head;
private transient Node<E> last;


Механизмы блокировки:


Две раздельные блокировки для вставки и удаления: putLock и takeLock.

private final ReentrantLock putLock = new ReentrantLock();
private final Condition notFull = putLock.newCondition();
private final ReentrantLock takeLock = new ReentrantLock();
private final Condition notEmpty = takeLock.newCondition();


Принцип работы:

Вставка элемента (put):
Захватывается блокировка putLock.
Проверяется, не превышает ли очередь максимальную емкость.
Создается новый узел и добавляется в конец очереди.
Если очередь была пустой, сигнализируется о наличии новых элементов (notEmpty.signal()).
Освобождается блокировка putLock.


Извлечение элемента (take):
Захватывается блокировка takeLock.
Проверяется, не пустая ли очередь.
Удаляется узел из начала очереди.
Если очередь была заполнена, сигнализируется о наличии свободного места (notFull.signal()).
Освобождается блокировка takeLock.


import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueExample {
public static void main(String[] args) {
LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(2);

// Вставка элементов
new Thread(() -> {
try {
queue.put(1);
System.out.println("Inserted 1");
queue.put(2);
System.out.println("Inserted 2");
queue.put(3);
System.out.println("Inserted 3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();

// Извлечение элементов
new Thread(() -> {
try {
Thread.sleep(2000);
System.out.println("Removed " + queue.take());
System.out.println("Removed " + queue.take());
System.out.println("Removed " + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}


Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://www.geeksforgeeks.org/linkedblockingqueue-class-in-java/
https://www.baeldung.com/java-queue-linkedblocking-concurrentlinked

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

import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueChallenge {
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
for (int i = 0; i < 10; i++) {
queue.put(i);
}

int result = 0;
while (!queue.isEmpty()) {
result += queue.take();
if (!queue.isEmpty()) {
queue.put(queue.take() * 2);
}
}

System.out.println("Result: " + result);
}
}


#Tasks
Варинаты ответа:
Anonymous Quiz
40%
115
30%
129
30%
126
0%
131