Многопоточность в Java: ExecutorService
ExecutorService — это интерфейс, который предоставляет методы для управления жизненным циклом потоков и для выполнения задач. Он является частью фреймворка java.util.concurrent и предоставляет гибкие способы работы с потоками.
Основные методы ExecutorService
submit(Runnable task): Отправляет задачу на выполнение и возвращает объект Future, представляющий эту задачу.
submit(Callable<T> task): Отправляет задачу, возвращающую результат, на выполнение и возвращает объект Future.
invokeAll(Collection<? extends Callable<T>> tasks): Выполняет все задачи из коллекции и возвращает список объектов Future.
invokeAny(Collection<? extends Callable<T>> tasks): Выполняет все задачи из коллекции и возвращает результат одной из успешно завершенных задач.
shutdown(): Начинает плавное завершение работы пула, позволяя выполнению текущих задач завершиться.
shutdownNow(): Пытается немедленно завершить выполнение всех задач.
Пример использования submit
Пример использования invokeAll и invokeAny
Управление завершением ExecutorService
Правильное завершение ExecutorService важно для предотвращения утечек ресурсов и корректного завершения программы.
shutdown(): Начинает плавное завершение. Новые задачи не принимаются, но уже отправленные задачи продолжают выполнение.
shutdownNow(): Пытается немедленно завершить все задачи, возвращает список задач, которые не были начаты.
awaitTermination(long timeout, TimeUnit unit): Ожидает завершения всех задач в течение указанного времени.
#Java #Training #Multithreading #Medium #ExecutorService
ExecutorService — это интерфейс, который предоставляет методы для управления жизненным циклом потоков и для выполнения задач. Он является частью фреймворка java.util.concurrent и предоставляет гибкие способы работы с потоками.
Основные методы ExecutorService
submit(Runnable task): Отправляет задачу на выполнение и возвращает объект Future, представляющий эту задачу.
submit(Callable<T> task): Отправляет задачу, возвращающую результат, на выполнение и возвращает объект Future.
invokeAll(Collection<? extends Callable<T>> tasks): Выполняет все задачи из коллекции и возвращает список объектов Future.
invokeAny(Collection<? extends Callable<T>> tasks): Выполняет все задачи из коллекции и возвращает результат одной из успешно завершенных задач.
shutdown(): Начинает плавное завершение работы пула, позволяя выполнению текущих задач завершиться.
shutdownNow(): Пытается немедленно завершить выполнение всех задач.
Пример использования submit
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class SubmitExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Callable<Integer> task1 = () -> {
Thread.sleep(1000);
return 10;
};
Callable<Integer> task2 = () -> {
Thread.sleep(2000);
return 20;
};
Future<Integer> future1 = executorService.submit(task1);
Future<Integer> future2 = executorService.submit(task2);
try {
System.out.println("Result of task1: " + future1.get());
System.out.println("Result of task2: " + future2.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
}
Пример использования invokeAll и invokeAny
public class InvokeExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
List<Callable<Integer>> tasks = Arrays.asList(
() -> {
Thread.sleep(1000);
return 1;
},
() -> {
Thread.sleep(2000);
return 2;
},
() -> {
Thread.sleep(3000);
return 3;
}
);
try {
List<Future<Integer>> results = executorService.invokeAll(tasks);
for (Future<Integer> result : results) {
System.out.println("Result: " + result.get());
}
Integer anyResult = executorService.invokeAny(tasks);
System.out.println("First completed task result: " + anyResult);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
}
Управление завершением ExecutorService
Правильное завершение ExecutorService важно для предотвращения утечек ресурсов и корректного завершения программы.
shutdown(): Начинает плавное завершение. Новые задачи не принимаются, но уже отправленные задачи продолжают выполнение.
executorService.shutdown();
shutdownNow(): Пытается немедленно завершить все задачи, возвращает список задач, которые не были начаты.
List<Runnable> notExecutedTasks = executorService.shutdownNow();
awaitTermination(long timeout, TimeUnit unit): Ожидает завершения всех задач в течение указанного времени.
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}
#Java #Training #Multithreading #Medium #ExecutorService
Concurrency
Concurrency (параллельность) — это способность программы выполнять несколько задач одновременно. В контексте Java, это включает использование многопоточности и синхронизации для обеспечения корректного выполнения параллельных операций.
Коллекции и многопоточность
Стандартные коллекции, такие как ArrayList, HashMap, HashSet и другие, не являются потокобезопасными. Это означает, что если несколько потоков одновременно выполняют операции чтения и записи с этими коллекциями, могут возникнуть проблемы, такие как:
Несогласованность данных: Данные могут быть повреждены или потеряны.
Исключения времени выполнения: Например, ConcurrentModificationException.
Для решения этих проблем в Java были введены потокобезопасные коллекции из пакета java.util.concurrent.
ConcurrentHashMap — это потокобезопасная реализация HashMap, которая позволяет нескольким потокам одновременно выполнять операции чтения и записи. В отличие от синхронизированного HashMap, ConcurrentHashMap использует механизм сегментации (локов), что позволяет повысить производительность за счет уменьшения количества блокировок.
Пример использования ConcurrentHashMap
В этом примере ConcurrentHashMap используется для параллельных операций чтения и записи. Поток writerThread добавляет элементы в карту, в то время как поток readerThread считывает значения из карты. Благодаря использованию ConcurrentHashMap данные остаются согласованными, и исключения времени выполнения не возникают.
Основные методы ConcurrentHashMap
put(K key, V value): Добавляет пару ключ-значение в карту.
get(Object key): Возвращает значение, связанное с указанным ключом.
remove(Object key): Удаляет пару ключ-значение из карты.
replace(K key, V value): Заменяет значение, связанное с указанным ключом, на новое значение.
computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction): Если ключ отсутствует в карте, вычисляет значение и добавляет его в карту.
#Java #Training #Multithreading #Medium
Concurrency (параллельность) — это способность программы выполнять несколько задач одновременно. В контексте Java, это включает использование многопоточности и синхронизации для обеспечения корректного выполнения параллельных операций.
Коллекции и многопоточность
Стандартные коллекции, такие как ArrayList, HashMap, HashSet и другие, не являются потокобезопасными. Это означает, что если несколько потоков одновременно выполняют операции чтения и записи с этими коллекциями, могут возникнуть проблемы, такие как:
Несогласованность данных: Данные могут быть повреждены или потеряны.
Исключения времени выполнения: Например, ConcurrentModificationException.
Для решения этих проблем в Java были введены потокобезопасные коллекции из пакета java.util.concurrent.
ConcurrentHashMap — это потокобезопасная реализация HashMap, которая позволяет нескольким потокам одновременно выполнять операции чтения и записи. В отличие от синхронизированного HashMap, ConcurrentHashMap использует механизм сегментации (локов), что позволяет повысить производительность за счет уменьшения количества блокировок.
Пример использования ConcurrentHashMap
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentHashMapExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
// Добавление элементов в карту
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);
concurrentMap.put("Three", 3);
// Создание потоков для параллельного чтения и записи
Thread writerThread = new Thread(() -> {
for (int i = 4; i <= 6; i++) {
concurrentMap.put("Number " + i, i);
System.out.println("Added: Number " + i);
try {
Thread.sleep(100); // Симуляция задержки
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread readerThread = new Thread(() -> {
for (int i = 1; i <= 6; i++) {
System.out.println("Value for Number " + i + ": " + concurrentMap.get("Number " + i));
try {
Thread.sleep(150); // Симуляция задержки
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
writerThread.start();
readerThread.start();
try {
writerThread.join();
readerThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
В этом примере ConcurrentHashMap используется для параллельных операций чтения и записи. Поток writerThread добавляет элементы в карту, в то время как поток readerThread считывает значения из карты. Благодаря использованию ConcurrentHashMap данные остаются согласованными, и исключения времени выполнения не возникают.
Основные методы ConcurrentHashMap
put(K key, V value): Добавляет пару ключ-значение в карту.
get(Object key): Возвращает значение, связанное с указанным ключом.
remove(Object key): Удаляет пару ключ-значение из карты.
replace(K key, V value): Заменяет значение, связанное с указанным ключом, на новое значение.
computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction): Если ключ отсутствует в карте, вычисляет значение и добавляет его в карту.
#Java #Training #Multithreading #Medium
Что выведет код?
#Tasks
public class AlgorithmChallenge {
public static void main(String[] args) {
int[] arr = {5, 3, 8, 6, 2};
int result = mysteriousFunction(arr);
System.out.println(result);
}
public static int mysteriousFunction(int[] arr) {
int n = arr.length;
int sum = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (arr[i] > arr[j]) {
sum += arr[i] - arr[j];
}
}
}
return sum;
}
}
#Tasks
Продвинутые методы ConcurrentHashMap
ConcurrentHashMap предоставляет дополнительные методы для более тонкого управления данными и выполнения атомарных операций.
Пример использования computeIfAbsent
Использование forEach и reduce
ConcurrentHashMap поддерживает методы для параллельной обработки данных, такие как forEach и reduce.
Пример использования forEach
Пример использования reduce
Примеры использования ConcurrentHashMap в реальных задачах
Пример 1: Подсчет количества слов
Пример 2: Кэширование вычислений
#Java #Training #Multithreading #Medium
ConcurrentHashMap предоставляет дополнительные методы для более тонкого управления данными и выполнения атомарных операций.
Пример использования computeIfAbsent
import java.util.concurrent.ConcurrentHashMap;
public class ComputeIfAbsentExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
// Добавление элементов в карту
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);
// Использование computeIfAbsent для добавления значения, если ключ отсутствует
concurrentMap.computeIfAbsent("Three", key -> 3);
concurrentMap.computeIfAbsent("One", key -> 10); // Это значение не будет добавлено, так как ключ уже существует
System.out.println(concurrentMap); // {One=1, Two=2, Three=3}
}
}
Использование forEach и reduce
ConcurrentHashMap поддерживает методы для параллельной обработки данных, такие как forEach и reduce.
Пример использования forEach
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
public class ForEachExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);
concurrentMap.put("Three", 3);
// Параллельная обработка элементов карты
concurrentMap.forEach(1, (key, value) -> {
System.out.println("Key: " + key + ", Value: " + value);
});
}
}
Пример использования reduce
import java.util.concurrent.ConcurrentHashMap;
public class ReduceExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("One", 1);
concurrentMap.put("Two", 2);
concurrentMap.put("Three", 3);
// Параллельное суммирование значений карты
int sum = concurrentMap.reduceValues(1, Integer::sum);
System.out.println("Sum of values: " + sum); // Output: Sum of values: 6
}
}
Примеры использования ConcurrentHashMap в реальных задачах
Пример 1: Подсчет количества слов
import java.util.concurrent.ConcurrentHashMap;
public class WordCountExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> wordCounts = new ConcurrentHashMap<>();
String[] words = {"apple", "banana", "apple", "orange", "banana", "apple"};
for (String word : words) {
wordCounts.merge(word, 1, Integer::sum);
}
System.out.println(wordCounts); // {apple=3, banana=2, orange=1}
}
}
Пример 2: Кэширование вычислений
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
public class ComputationCacheExample {
private final ConcurrentHashMap<Integer, String> cache = new ConcurrentHashMap<>();
public String compute(Integer key, Function<Integer, String> computation) {
return cache.computeIfAbsent(key, computation);
}
public static void main(String[] args) {
ComputationCacheExample example = new ComputationCacheExample();
Function<Integer, String> computation = key -> {
try {
Thread.sleep(1000); // Симуляция долгого вычисления
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Result for " + key;
};
System.out.println(example.compute(1, computation)); // Вычисление и кэширование
System.out.println(example.compute(1, computation)); // Использование закэшированного значения
}
}
#Java #Training #Multithreading #Medium
Аннотации в Java
Аннотации в Java — это метаданные, которые добавляются к коду для предоставления дополнительной информации. Они могут быть использованы компилятором, инструментами разработки и во время выполнения (через рефлексию). Аннотации не изменяют логики программы, но могут влиять на её поведение.
Основные встроенные аннотации
@ Override: Указывает, что метод переопределяет метод суперкласса.
@ Deprecated: Обозначает, что элемент (метод, класс, поле) устарел и не рекомендуется к использованию.
@ SuppressWarnings: Подавляет указанные предупреждения компилятора.
@ SafeVarargs: Обозначает, что метод с переменным числом аргументов не выполняет потенциально небезопасных операций с varargs.
@ FunctionalInterface: Указывает, что интерфейс является функциональным и содержит только один абстрактный метод.
Примеры использования встроенных аннотаций
Методы аннотаций
Аннотации могут содержать методы. Методы аннотаций могут иметь значения по умолчанию.
Аннотацию можно использовать с параметрами:
Аннотации и рефлексия
Аннотации можно считывать во время выполнения с помощью рефлексии. Это позволяет динамически изменять поведение программы в зависимости от аннотированных элементов.
Пример использования рефлексии для чтения аннотаций
#Java #Training #Annotation #Medium
Аннотации в Java — это метаданные, которые добавляются к коду для предоставления дополнительной информации. Они могут быть использованы компилятором, инструментами разработки и во время выполнения (через рефлексию). Аннотации не изменяют логики программы, но могут влиять на её поведение.
Основные встроенные аннотации
@ Override: Указывает, что метод переопределяет метод суперкласса.
@ Deprecated: Обозначает, что элемент (метод, класс, поле) устарел и не рекомендуется к использованию.
@ SuppressWarnings: Подавляет указанные предупреждения компилятора.
@ SafeVarargs: Обозначает, что метод с переменным числом аргументов не выполняет потенциально небезопасных операций с varargs.
@ FunctionalInterface: Указывает, что интерфейс является функциональным и содержит только один абстрактный метод.
Примеры использования встроенных аннотаций
public class AnnotationExample {
@Override
public String toString() {
return "AnnotationExample";
}
@Deprecated
public void oldMethod() {
System.out.println("This method is deprecated");
}
@SuppressWarnings("unchecked")
public void uncheckedOperation() {
List rawList = new ArrayList();
rawList.add("String");
}
@SafeVarargs
public final void safeVarargsMethod(List<String>... lists) {
for (List<String> list : lists) {
System.out.println(list);
}
}
@FunctionalInterface
interface MyFunctionalInterface {
void execute();
}
}
Методы аннотаций
Аннотации могут содержать методы. Методы аннотаций могут иметь значения по умолчанию.
@interface MyAnnotation {
String value();
int number() default 42;
}
Аннотацию можно использовать с параметрами:
@MyAnnotation(value = "Example", number = 10)
public class AnnotatedClass {
}
Аннотации и рефлексия
Аннотации можно считывать во время выполнения с помощью рефлексии. Это позволяет динамически изменять поведение программы в зависимости от аннотированных элементов.
Пример использования рефлексии для чтения аннотаций
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class ReflectionExample {
@MyAnnotation(value = "Test", number = 5)
public void annotatedMethod() {
}
public static void main(String[] args) throws Exception {
Method method = ReflectionExample.class.getMethod("annotatedMethod");
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println("Value: " + annotation.value());
System.out.println("Number: " + annotation.number());
}
}
}
#Java #Training #Annotation #Medium
Что выведет код?
#Tasks
public class ConcatChallenge {
public static void main(String[] args) {
String[] arr = {"Java", "is", "fun"};
String result = mysteriousConcat(arr);
System.out.println(result);
}
public static String mysteriousConcat(String[] arr) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]);
if (i < arr.length - 1) {
sb.append("-");
}
}
return sb.toString();
}
}
#Tasks
Создание собственных аннотаций в Java
Создание собственных аннотаций позволяет добавлять метаданные к вашему коду, которые могут быть использованы компилятором, инструментами разработки или во время выполнения. Аннотации можно использовать для валидации данных, конфигурации и других задач.
Для создания аннотации используется ключевое слово @ interface.
@ Retention: Указывает, насколько долго аннотация сохраняется (например, только в исходном коде, в классе или во время выполнения).
RetentionPolicy.SOURCE: Аннотация сохраняется только в исходном коде и отбрасывается компилятором.
RetentionPolicy.CLASS: Аннотация сохраняется в файле класса, но не доступна во время выполнения.
RetentionPolicy.RUNTIME: Аннотация сохраняется во время выполнения и может быть прочитана с помощью рефлексии.
Применение собственной аннотации
Чтение аннотаций с помощью рефлексии
Методы аннотаций
Аннотации могут содержать методы, которые определяют параметры аннотации. Методы могут иметь значения по умолчанию.
Пример использования:
Ограничения и мета-аннотации
Мета-аннотации — это аннотации, которые применяются к другим аннотациям. В Java существует несколько мета-аннотаций:
@ Retention: Указывает, насколько долго аннотация сохраняется.
@ Target: Указывает, где аннотация может быть применена (например, к методам, полям, классам).
@ Inherited: Указывает, что аннотация может быть унаследована подклассами.
@ Documented: Указывает, что аннотация должна быть задокументирована с помощью javadoc.
Пример использования мета-аннотаций:
Пример практического использования собственных аннотаций
Валидация с помощью аннотаций
Создадим аннотацию для проверки полей класса:
#Java #Training #Annotation #Medium
Создание собственных аннотаций позволяет добавлять метаданные к вашему коду, которые могут быть использованы компилятором, инструментами разработки или во время выполнения. Аннотации можно использовать для валидации данных, конфигурации и других задач.
Для создания аннотации используется ключевое слово @ interface.
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
String value();
int number() default 42;
}
@ Retention: Указывает, насколько долго аннотация сохраняется (например, только в исходном коде, в классе или во время выполнения).
RetentionPolicy.SOURCE: Аннотация сохраняется только в исходном коде и отбрасывается компилятором.
RetentionPolicy.CLASS: Аннотация сохраняется в файле класса, но не доступна во время выполнения.
RetentionPolicy.RUNTIME: Аннотация сохраняется во время выполнения и может быть прочитана с помощью рефлексии.
Применение собственной аннотации
@MyCustomAnnotation(value = "Example", number = 10)
public class CustomAnnotatedClass {
}
Чтение аннотаций с помощью рефлексии
import java.lang.annotation.Annotation;
public class CustomAnnotationReflection {
public static void main(String[] args) {
Class<CustomAnnotatedClass> clazz = CustomAnnotatedClass.class;
if (clazz.isAnnotationPresent(MyCustomAnnotation.class)) {
MyCustomAnnotation annotation = clazz.getAnnotation(MyCustomAnnotation.class);
System.out.println("Value: " + annotation.value());
System.out.println("Number: " + annotation.number());
}
}
}
Методы аннотаций
Аннотации могут содержать методы, которые определяют параметры аннотации. Методы могут иметь значения по умолчанию.
public @interface DetailedAnnotation {
String description();
boolean enabled() default true;
}
Пример использования:
@DetailedAnnotation(description = "This is a detailed annotation", enabled = false)
public class DetailedAnnotatedClass {
}
Ограничения и мета-аннотации
Мета-аннотации — это аннотации, которые применяются к другим аннотациям. В Java существует несколько мета-аннотаций:
@ Retention: Указывает, насколько долго аннотация сохраняется.
@ Target: Указывает, где аннотация может быть применена (например, к методам, полям, классам).
@ Inherited: Указывает, что аннотация может быть унаследована подклассами.
@ Documented: Указывает, что аннотация должна быть задокументирована с помощью javadoc.
Пример использования мета-аннотаций:
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MultiTargetAnnotation {
String value();
}
Пример практического использования собственных аннотаций
Валидация с помощью аннотаций
Создадим аннотацию для проверки полей класса:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotNull {
}
Применим аннотацию к классу:
java
Копировать код
public class User {
@NotNull
private String name;
public User(String name) {
this.name = name;
}
}
#Java #Training #Annotation #Medium
Создадим метод для проверки полей:
Этот пример показывает, как создавать и использовать собственные аннотации для выполнения валидации данных. Аннотации делают код более читаемым и структурированным, позволяя легко добавлять новые проверки и конфигурации.
#Java #Training #Annotation #Medium
import java.lang.reflect.Field;
public class Validator {
public static void validate(Object object) throws IllegalAccessException {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(NotNull.class)) {
field.setAccessible(true);
Object value = field.get(object);
if (value == null) {
throw new IllegalArgumentException(field.getName() + " cannot be null");
}
}
}
}
public static void main(String[] args) {
User user = new User(null);
try {
validate(user);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
Этот пример показывает, как создавать и использовать собственные аннотации для выполнения валидации данных. Аннотации делают код более читаемым и структурированным, позволяя легко добавлять новые проверки и конфигурации.
#Java #Training #Annotation #Medium
Всем доброго субботнего утра! ☀️
Как ваше настроение, какие планы на выходные?
Делитесь с нами в чате - https://t.me/Java_Beginner_chat
Напоминаю, что завтра в 16:00 по МСК запланирована онлайн встреча, где мы наконец-то закончим наше консольное TODO приложение!)))
Как ваше настроение, какие планы на выходные?
Делитесь с нами в чате - https://t.me/Java_Beginner_chat
Напоминаю, что завтра в 16:00 по МСК запланирована онлайн встреча, где мы наконец-то закончим наше консольное TODO приложение!)))
Утро программиста.
#Mems
объекты: Жена, Будильник, Автомобиль;
переменные: совесть, желание_спать, сытость, злость
если Будильник = 1
{
перевести(5min);
перевести(5min);
выключить();
встать();
}
если Будильник = 0
{
пока (совесть < желание_спать)
{
спать();
}
встать();
}
умыться();
если Жена > 0
{
приготовить_завтрак(жена);
}
если Жена = 0
{
приготовить_завтрак(содержимое холодильника[0]);
}
сытость = сытость + 1;
если автомобиль !=1
{
добраться_до_работы(спать());
}
если автомобиль =1
{
добраться_до_работы(злость);
}
#Mems
Напоминаю про канал моего товарища 3D-шника) - https://t.me/model3ddd/3511
Если вас интересует данная тема, есть желание изучить ее подробнее, ознакомиться с примерами работ - залетайте не думая!
Если вас интересует данная тема, есть желание изучить ее подробнее, ознакомиться с примерами работ - залетайте не думая!
Telegram
3Dshnik
📱 Все: мы будем использовать ChatGPT для революций в науке и технике
Мы используем ChatGPT:
3Dshnik - Подписаться
Мы используем ChatGPT:
3Dshnik - Подписаться
А вы придете на онлайн встречу в 16:00 по МСК сегодня?
Anonymous Poll
42%
Да, я буду!)
50%
Хотел бы, но не могу(
0%
Нет, нафиг мне это надо?)))
8%
Что это за канал?)
This media is not supported in your browser
VIEW IN TELEGRAM
Запись нашей сегодняшней встречи -
https://youtu.be/QGPf_ki7V1c
Огромная благодарность тем кто был, за участие и подсказки, без Вас было б скучнее))))
Мы наконец то закончили консольную записную книжку, написанную в самом простом варианте, понятном даже для новичков.
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб канал!
Гит репозиторий с результатом - https://github.com/Oleborn/Notebook
Всем лучей добра)⭐️
https://youtu.be/QGPf_ki7V1c
Огромная благодарность тем кто был, за участие и подсказки, без Вас было б скучнее))))
Мы наконец то закончили консольную записную книжку, написанную в самом простом варианте, понятном даже для новичков.
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб канал!
Гит репозиторий с результатом - https://github.com/Oleborn/Notebook
Всем лучей добра)⭐️
HashMap структура и внутреннее устройство.
HashMap — это одна из наиболее часто используемых структур данных в программировании, обеспечивающая хранение пар "ключ-значение" с возможностью быстрой вставки, удаления и поиска данных.
Основные характеристики HashMap:
Ключи и значения: Хранит пары "ключ-значение".
Хэш-функция: Использует хэш-функцию для вычисления индекса, по которому будет храниться элемент.
Бакеты: Внутренне HashMap представляет собой массив бакетов (корзин).
Связанный список или дерево в бакетах: При коллизии (когда разные ключи имеют одинаковый хэш) используется либо связанный список, либо сбалансированное дерево (в современных реализациях).
Внутреннее устройство HashMap
HashMap использует массив, где каждый элемент называется бакетом. Каждому ключу через хэш-функцию сопоставляется индекс бакета.
Бакеты
Бакет — это место для хранения пары "ключ-значение". Если несколько ключей попадают в один и тот же бакет (коллизия), они хранятся в виде связанного списка или красно-черного дерева.
Связанный список и дерево в бакетах
Когда происходит коллизия, в бакете начинается формироваться структура данных:
Связанный список: В более старых реализациях Java при коллизии использовался связанный список.
Красно-черное дерево: Начиная с Java 8, при определенном числе элементов в бакете связанный список преобразуется в красно-черное дерево для улучшения производительности.
Хэш-функция
HashMap использует метод hashCode() ключа для вычисления его хэш-кода, который затем преобразуется в индекс бакета с использованием операции побитового AND с размером массива минус один.
Алгоритм поиска
Вычисление хэш-кода: Сначала вычисляется хэш-код ключа.
Вычисление индекса бакета: Индекс вычисляется с использованием операции побитового AND.
Поиск в бакете: В бакете выполняется последовательный поиск в связанном списке или дерево-поиск, если это красно-черное дерево.
Сложность поиска
В среднем: O(1) для поиска, вставки и удаления. Это достигается благодаря равномерному распределению элементов по бакетам с использованием хорошей хэш-функции.
В худшем случае: O(n), если все ключи попадают в один бакет, и при этом используется связанный список. В случае использования красно-черного дерева сложность поиска в худшем случае будет O(log n).
Пример работы с коллизиями
В этом примере ключи 1 и 17 могут попасть в один бакет, в зависимости от размера массива и хэш-функции, что демонстрирует ситуацию с коллизией.
Полезные ссылки для более полного ознакомления с HashMap (спасибо авторам за их кропотливую работу):
https://habr.com/ru/articles/128017/
https://javarush.com/groups/posts/2496-podrobnihy-razbor-klassa-hashmap
#Java #Training #Medium #HashMap
HashMap — это одна из наиболее часто используемых структур данных в программировании, обеспечивающая хранение пар "ключ-значение" с возможностью быстрой вставки, удаления и поиска данных.
Основные характеристики HashMap:
Ключи и значения: Хранит пары "ключ-значение".
Хэш-функция: Использует хэш-функцию для вычисления индекса, по которому будет храниться элемент.
Бакеты: Внутренне HashMap представляет собой массив бакетов (корзин).
Связанный список или дерево в бакетах: При коллизии (когда разные ключи имеют одинаковый хэш) используется либо связанный список, либо сбалансированное дерево (в современных реализациях).
Внутреннее устройство HashMap
HashMap использует массив, где каждый элемент называется бакетом. Каждому ключу через хэш-функцию сопоставляется индекс бакета.
Бакеты
Бакет — это место для хранения пары "ключ-значение". Если несколько ключей попадают в один и тот же бакет (коллизия), они хранятся в виде связанного списка или красно-черного дерева.
Связанный список и дерево в бакетах
Когда происходит коллизия, в бакете начинается формироваться структура данных:
Связанный список: В более старых реализациях Java при коллизии использовался связанный список.
Красно-черное дерево: Начиная с Java 8, при определенном числе элементов в бакете связанный список преобразуется в красно-черное дерево для улучшения производительности.
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
// Вставка элементов
map.put("One", 1);
map.put("Two", 2);
map.put("Three", 3);
// Поиск элементов
System.out.println("Value for key 'Two': " + map.get("Two"));
// Удаление элемента
map.remove("One");
System.out.println("Map after removing 'One': " + map);
}
}
Хэш-функция
HashMap использует метод hashCode() ключа для вычисления его хэш-кода, который затем преобразуется в индекс бакета с использованием операции побитового AND с размером массива минус один.
Алгоритм поиска
Вычисление хэш-кода: Сначала вычисляется хэш-код ключа.
Вычисление индекса бакета: Индекс вычисляется с использованием операции побитового AND.
Поиск в бакете: В бакете выполняется последовательный поиск в связанном списке или дерево-поиск, если это красно-черное дерево.
Сложность поиска
В среднем: O(1) для поиска, вставки и удаления. Это достигается благодаря равномерному распределению элементов по бакетам с использованием хорошей хэш-функции.
В худшем случае: O(n), если все ключи попадают в один бакет, и при этом используется связанный список. В случае использования красно-черного дерева сложность поиска в худшем случае будет O(log n).
Пример работы с коллизиями
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
// Эти два разных ключа могут дать одинаковый хэш-код
map.put(1, "One");
map.put(17, "Seventeen");
// Оба ключа будут находиться в одном бакете
System.out.println("Value for key 1: " + map.get(1));
System.out.println("Value for key 17: " + map.get(17));
}
}
В этом примере ключи 1 и 17 могут попасть в один бакет, в зависимости от размера массива и хэш-функции, что демонстрирует ситуацию с коллизией.
Полезные ссылки для более полного ознакомления с HashMap (спасибо авторам за их кропотливую работу):
https://habr.com/ru/articles/128017/
https://javarush.com/groups/posts/2496-podrobnihy-razbor-klassa-hashmap
#Java #Training #Medium #HashMap
Хабр
Структуры данных в картинках. HashMap
Приветствую вас, хабрачитатели! Продолжаю попытки визуализировать структуры данных в Java. В предыдущих сериях мы уже ознакомились с ArrayList и LinkedList , сегодня же рассмотрим HashMap. HashMap —...
Что выведет код?
#Tasks
public class ArithmeticChallenge {
public static void main(String[] args) {
int result = mysteriousArithmetic(3, 2);
System.out.println(result);
}
public static int mysteriousArithmetic(int a, int b) {
int result = 0;
for (int i = 1; i <= a; i++) {
result += (i % 2 == 0) ? (i * b) : (i + b);
}
return result;
}
}
#Tasks