Thread - это класс, некоторая надстройка над физическим потоком.Runnable - это интерфейс, представляющий абстракцию над выполняемой задачей.Интерфейс
Runnable позволяет логически отделить логику выполнения задачи от непосредственного управления потоком.#java #Thread #Runnable
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2
Интерфейс
CharSequence представляет собой последовательность символов и является базовым интерфейсом для работы с различными строковыми типами. Он был введён в Java начиная с версии 1.4 и служит для предоставления общего интерфейса для объектов, которые могут быть представлены как последовательность символов.CharSequence реализован такими классами, как:String — неизменяемая строка.StringBuilder — изменяемая последовательность символов.StringBuffer — изменяемая, но потокобезопасная последовательность символов.CharSequence определяет несколько методов, которые предоставляют доступ к символам последовательности и информации о ней:
int length();
Возвращает количество символов в последовательности.
char charAt(int index);
Возвращает символ по указанному индексу.
CharSequence subSequence(int start, int end);
Возвращает новую последовательность символов, которая является подстрокой оригинальной последовательности. Индекс
start включается, а end — нет.
String toString();
Возвращает строковое представление последовательности символов.
CharSequence cs = "Hello, World!";
System.out.println("Length: " + cs.length());
System.out.println("Char at index 1: " + cs.charAt(1));
System.out.println("Subsequence (0, 5): " + cs.subSequence(0, 5));
System.out.println("String: " + cs.toString());
Вывод:
Length: 13
Char at index 1: e
Subsequence (0, 5): Hello
String: Hello, World!
#java #CharSequence
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🥰1
🔥7❤1🤔1🎉1
Потоки данных поддерживают метод
skip(n), возвращающий поток данных с отброшенными первыми n элементами источника. Если в потоке-источнике было меньше n элементов, возвращается пустой поток.Например, следующий код пропускает первые два блюда, содержащие более 300 калорий, и возвращает остальные:
List<Dish> dishes = menu
.stream()
.filter(d -> d.getCalories() > 300)
.skip(2)
.collect(toList());
#java #stream #skip
Please open Telegram to view this post
VIEW IN TELEGRAM
👏7❤3
Внутри много интересного, например Markdown документация, поддержка примитивных типов в паттернах и операторах
instanceof / switch и многое другое.Появился еще один тип классов - неявный, как будто существующих нам было мало 😁
Теперь приложение может стартовать даже если метод
main не статический и не содержит параметр String[] args:
// --enable-preview --source 23
class HelloWorld {
void main() {
System.out.println("Hello, World!");
}
}
В таком случае во время запуска JVM сама создаст экземпляр класса
HelloWorld и вызовет у него метод main():
$ java --enable-preview --source 23 HelloWorld.java
Hello, World!
И даже вот так!:
// HelloWorld.java
String greeting = "Hello, World!";
void main() {
println(greeting);
}
То есть вообще не объявляя класса! В таком случае виртуальная машина сама объявит неявный класс, в который поместит метод
main() и другие верхнеуровневые объявления в файле. Фишка здесь еще и в том что используется метод println() вместо System.out.println(), это возможно из-за того что в неявный класс по умолчанию импортируется новый класс java.io.IO, в котором есть соответствующий метод.Подробнее можно почитать на Habr'е.
#java23
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Вышла Java 23
Вышла общедоступная версия Java 23 . В этот релиз попало около 2400 закрытых задач и 12 JEP'ов . Release Notes можно посмотреть здесь . Полный список изменений API – здесь . Java 23 не является...
1👍14😢8❤4
Ромбовидное наследование (diamond inheritance) — ситуация в объектно-ориентированных языках программирования с поддержкой множественного наследования, когда два класса B и C наследуют от A, а класс D наследует от обоих классов B и C. При этой схеме наследования может возникнуть неоднозначность: если объект класса D вызывает метод, определенный в классе A (и этот метод не был переопределен в классе D), а классы B и C по-своему переопределили этот метод, то от какого класса его наследовать: B или C?
В Java множественное наследование не разрешено для классов и разрешено только для интерфейсов, чтобы устранить эту серьезную проблему.
#java #diamond #problem
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🥰1
🎉10👍2
Метод
anyMatch служит для ответа на вопрос: «Удовлетворяет ли заданному предикату хотя бы один элемент из потока данных?»Метод
anyMatch возвращает boolean, а значит, является завершающей (терминальной) операцией.
int[] digits = {1, 3, 5, 7, 2, 9};
boolean result = Arrays.stream(digits).anyMatch(d -> d % 2 == 0);
System.out.println(result); // true
#java #Stream #anyMatch
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14
Метод
allMatch проверяет, удовлетворяют ли заданному предикату все элементы потока данных.
// Все не чётные?
int[] digits = {1, 3, 5, 7, 9};
boolean result = Arrays.stream(digits).allMatch(d -> d % 2 != 0);
System.out.println(result); // true
Противоположностью
allMatch является метод noneMatch. Он проверяет, точно ли ни один элемент списка не соответствует заданному предикату.
// Нет чётных?
int[] digits = {1, 3, 5, 7, 9};
boolean result = Arrays.stream(digits).noneMatch(d -> d % 2 == 0);
System.out.println(result); // true
#java #Stream #allMatch #noneMatch
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
🥱11👍3👏2🎉1
~ Побитовый унарный оператор NOT;& Побитовый AND;&= Побитовый AND с присваиванием;| Побитовый OR;|= Побитовый OR с присваиванием;^ Побитовый исключающее XOR;^= Побитовый исключающее XOR с присваиванием;>> Сдвиг вправо (деление на 2 в степени сдвига);>>= Сдвиг вправо с присваиванием;>>> Сдвиг вправо без учёта знака;>>>= Сдвиг вправо без учёта знака с присваиванием;<< Сдвиг влево (умножение на 2 в степени сдвига);<<= Сдвиг влево с присваиванием.#java #bitwise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1🔥1
Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false
Integer x = 1;
Integer y = 1;
System.out.println(x == y); // true
Это не просто волшебство! Это связано с целочисленным кэшированием в Java.
Для значений в диапазоне от -128 до 127 объекты типа
Integer кэшируются, и ссылки на них одинаковы, а для значений за пределами этого диапазона создаются новые объекты, и ссылки на них будут разными. Так как используется оператор ==, то сравниваются ссылки на объекты.#java #magic
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🤔17❤4👏1🌭1
Метод
reduce в интерфейсе Stream используется для сведения набора элементов потока к одному результату, применяя заданную бинарную операцию (например, сложение, умножение). Этот метод часто используется для агрегации данных.Допустим, у нас есть список чисел, и мы хотим найти их сумму:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
System.out.println(sum); // 15
В этом примере:
0 — начальное значение (identity),(a, b) -> a + b — бинарная операция, которая складывает два значения.reduce полезен для таких операций, как сумма, произведение, объединение строк и т.д.#java #Stream #reduce
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1🔥1
Метод
deepToString из класса Arrays используется для создания строкового представления многомерных массивов (например, массивов массивов). Он обходит каждый уровень вложенности массива и выводит его элементы в виде строки. Это удобно для работы с многомерными массивами, так как стандартный метод toString не раскрывает их структуру.Пример использования:
int[][] array = {{1, 2, 3}, {4, 5, 6}};
System.out.println(Arrays.deepToString(array));
// [[1, 2, 3], [4, 5, 6]]
Этот метод работает рекурсивно, обеспечивая полное отображение структуры массива любой вложенности.
#java #Arrays #deepToString
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤2
Последовательные потоки (Sequential Streams)
✔️ Обрабатывают элементы последовательно, один за другим, на одном потоке, следовательно производительность ограничена возможностями одного ядра процессора.
✔️ Используют основной поток программы (main thread) для выполнения операций.
✔️ Метод stream() создаёт последовательный поток.
Пример последовательного потока:
List<String> list = List.of("Hello ", "w", "o", "r", "l", "d!");
list.stream().forEach(System.out::print);
// Hello world!
Параллельные потоки (Parallel Streams)
✔️ Обрабатывают элементы параллельно, распределяя их между несколькими потоками (threads), что позволяет использовать многопоточность.
✔️ Используют ForkJoinPool для распределения задач между потоками.
✔️ Эффективны для больших наборов данных, поскольку могут улучшить производительность на многоядерных процессорах.
✔️ Параллельный поток можно создать, вызвав метод parallelStream() или применив метод parallel() к уже существующему потоку.
Пример параллельного потока:
List<String> list = List.of("Hello ", "w", "o", "r", "l", "d!");
list.parallelStream().forEach(System.out::print);
// rlHello d!wo
#java #Stream #parallelStream
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2🔥1😁1
java.util.concurrent.Использует подход "разделяй и властвуй", где задача разбивается на подзадачи до тех пор, пока они не станут достаточно маленькими для последовательного решения. Для этого используются классы
RecursiveTask<V> (возвращает результат) и RecursiveAction (без результата).ForkJoinPool динамически управляет количеством потоков, при необходимости создавая новые. Обычно это количество соответствует числу процессоров, доступных в системе.
Использует технику work-stealing, где потоки, завершившие свои задачи, могут "красть" задачи у других потоков, чтобы эффективно использовать ресурсы процессора.
ForkJoinPool обладает высокой производительностью для задач, которые можно разбить на независимые подзадачи.
Основные методы:
invoke(): синхронно запускает задачу и ждет её завершения.
submit(): запускает задачу асинхронно.
execute(): также запускает задачу асинхронно, но не возвращает результат.
Пример использования:
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class SumTask extends RecursiveTask<Integer> {
private final int[] array;
private final int start, end;
private final int threshold = 10;
public SumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= threshold) {
// Базовый случай: небольшая задача
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
} else {
// Разделяем задачу
int mid = (start + end) / 2;
SumTask leftTask = new SumTask(array, start, mid);
SumTask rightTask = new SumTask(array, mid, end);
leftTask.fork(); // Асинхронно запускаем левую подзадачу
int rightResult = rightTask.compute(); // Синхронно вычисляем правую подзадачу
int leftResult = leftTask.join(); // Ждем завершения левой подзадачи
return leftResult + rightResult;
}
}
}
public class ForkJoinExample {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
SumTask task = new SumTask(array, 0, array.length);
int result = pool.invoke(task);
System.out.println("Сумма: " + result);
}
}
Этот код создает задачу для суммирования массива, разбивая его на подзадачи.
#java #ForkJoinPool
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤1🔥1