Deque
отличается гибкостью и производительностью, превосходя тем самым Stack
. Являясь частью Java Collections Framework, Deque
предлагает как механизмы работы LIFO (стек), так и FIFO (очередь), предоставляя разнообразные высокопроизводительные реализации, например ArrayDeque
, что выделяет его на фоне устаревшего и предназначенного для однопоточности класса Stack
.ArrayDeque
можно использовать в качестве стека:Deque<Integer> stack = new ArrayDeque<>();
stack.push(1); // добавить элемент — easy
int top = stack.peek(); // Взять верхний элемент легко
int pop = stack.pop(); // ...как и нижний
Короче, выбирайте
Deque
для надежной и эффективной реализации стекаDeque
можно найти тут@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Полезно понимать ограничения и достоинства инструмента, так что держите:
Null
являются частью языка Java.@android_its
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
java.lang.NullPointerException
и почему оно может происходить?Какие методы и средства использовать, чтобы определить причину возникновения этого исключения, приводящего к преждевременному прекращению работы приложения?
Ответ и решение
int
:int x;
x = 10;
В этом примере переменная
x
имеет тип int
и Java инициализирует её как 0. Когда вы присвоите переменной значение 10 (вторая строка), это значение сохранится в ячейке памяти, на которую ссылается x
.Integer num;
num = new Integer(10);
В первой строке объявлена переменная
num
, ее тип не относится к встроенному, следовательно, значением является ссылка (тип этой переменной, Integer
, является ссылочным типом). Поскольку вы еще не указали, на что собираетесь ссылаться, Java присвоит переменной значение Null
, подразумевая «Я ни на что не ссылаюсь».Во второй строке, ключевое слово
new
используется для создания объекта типа Integer
. Этот объект имеет адрес в памяти, который присваивается переменной num
. Теперь, с помощью переменной num
вы можете обратиться к объекту используя оператора разыменования .
.java.lang.NullPointerException
возникает, если вы объявили переменную, но не создали объект, то есть если вы попытаетесь разыменовать num
до того, как создали объект, вы получите NullPointerException
. В самом простом случае, компилятор обнаружит проблему и сообщит, чтоnum may not have been initialized
Что говорит: «возможно, переменная
num
не инициализирована».public void doSomething(Integer num){
// Работаем с num
}
В этом случае создание объекта (переменная
num
) лежит на вызывающем коде, то есть вы предполагаете, что он был создан ранее – до вызова метода doSomething
. К сожалению, следующий вызов метода вполне возможен:doSomething(null);
В этом случае значение переменной
num
будет null
. Лучшим способом избежать данного исключения будет проверка на равенство нулю. Как результат, функция doSomething
должна быть переписана следующим образом:public void doSomething(Integer num){
if (num != null) {
// Работаем с num
}
}
IllegalArgumentException
.public void doSomething(Integer num){
if (num == null)
throw new IllegalArgumentException("Num не должен быть null");
// Работаем с num
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Повторение — мать учения и основа научного метода, так что приступим)
В Java подстрока (
substring
) относится к непрерывной последовательности символов внутри данной строки. Она позволяет извлекать сегменты текстовых данных на основе начальных и конечных индексов. substring()
Метод
substring()
используется для извлечения подстрок из заданной строки в Java. Он поставляется в 2 версиях:substring(int BeginIndex)
— этот метод извлекает символы из указанного значения BeginIndex
до конца строки.substring(int BeginIndex, int EndIndex)
— этот метод извлекает символы от BeginIndex
до (но не включая) EndIndex
.substring()
public class SubstringExample {
public static void main(String[] args) {
String originalString = "Java is amazing!";
// Извлекаем подстроку от индекса 5 до конца
String substring1 = originalString.substring(5);
System.out.println("Substring 1: " + substring1);
// Извлекаем подстроку с индексом от 0 до 4 (исключая)
String substring2 = originalString.substring(0, 4);
System.out.println("Substring 2: " + substring2);
}
}
—
substring1
начинается с индекса 5 ("i"
) и до конца строки, в результате чего получается "is amazing!"
—
substring2
, начиная с индекса 0 ("J"
) до (но не включая) индекс 4 ("a"
), в результате чего получается "Java"
substring()
IndexOutOfBoundsException
.@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
java.util.Date
для хранения значений дат и java.util.Calendar
для увеличения от одной даты к другой.Давайте рассмотрим пример использования простого цикла
while
вместе с классами java.util.Date
и java.util.Calendar
:void iterateBetweenDatesJava7(Date start, Date end) {
Date current = start;
while (current.before(end)) {
processDate(current);
Calendar calendar = Calendar.getInstance();
calendar.setTime(current);
calendar.add(Calendar.DATE, 1);
current = calendar.getTime();
}
}
java.util.Calendar
, для увеличения дат.Давайте воспользуемся
LocalDate
и методом plusDays(1)
для перемещения вперед по диапазону дат:void iterateBetweenDatesJava8(LocalDate start, LocalDate end) {
for (LocalDate date = start; date.isBefore(end); date = date.plusDays(1)) {
processDate(date);
}
}
Здесь стоит отметить, что хотя Stream API доступен, начиная с Java 8, итерация между двумя датами с использованием Date API в сочетании с Stream API невозможна до Java 9.
dateUntil,
который позволяет нам использовать Stream API для итерации от даты начала до даты окончания.Давайте обновим код нашего примера, чтобы воспользоваться этой функцией:
void iterateBetweenDatesJava9(LocalDate start, LocalDate end) {
start.datesUntil(end).forEach(this::processDate);
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Double.POSITIVE_INFINITY
для положительной бесконечности и Double.NEGATIVE_INFINITY
для отрицательной:double posInf = Double.POSITIVE_INFINITY; // +∞
double negInf = Double.NEGATIVE_INFINITY; // -∞
double posInfCalc = 1.0 / 0.0; // +∞
double negInfCalc = -1.0 / 0.0; // -∞
Внимание: в случае целочисленного деления на ноль возникает исключение
ArithmeticException
, поэтому для операций с бесконечностями используйте типы float
или double
.Обработка бесконечностей в Java основывается на стандарте IEEE 754 и следует правилам:
Double.POSITIVE_INFINITY + anyPositiveDouble
всегда будет равно Double.POSITIVE_INFINITY
.NaN
(не число).Double.POSITIVE_INFINITY
на отрицательное число приводит к Double.NEGATIVE_INFINITY
и наоборот.Double.POSITIVE_INFINITY
даст ноль.В зависимости от специфики задачи и требуемой точности можно использовать типы
Double
или Float
.При проведении операций сравнения с бесконечностями учтите:
Double.POSITIVE_INFINITY
всегда больше любого конечного значения, в то время как Double.NEGATIVE_INFINITY
всегда меньше.NaN
лучше производить с помощью Double.isNaN()
, так как любое равенство с NaN
возвращает false
.Double.POSITIVE_INFINITY
равно Double.POSITIVE_INFINITY
, что также верно и для отрицательной бесконечности.@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
when
проверяет значение некоторого объекта и в зависимости от его значения выполняет тот или иной код. Конструкция when
аналогична конструкции switch
в других языках. Формальное определение:
значение1 -> действия1
значение2 -> действия2
...
значениеN -> действияN
}
when
, то выполняются соответствующие действия, которые идут после оператора ->
после соответствующего значения:
fun main() {
val isEnabled = true
when(isEnabled){
false -> println("isEnabled off")
true -> println("isEnabled on")
}
}
Здесь в качестве объекта в конструкцию
when
передается переменная isEnabled
. Далее ее значение по порядку сравнивается со значениями в false
и true
. В данном случае переменная isEnabled
равна true
, поэтому будет выполняться код:println("isEnabled on")
В примере выше
isEnabled
имела только 2 возможных варианта: true
и false
. Однако чаще бывают случаи, когда значения в блоке when
не покрывают все возможные значения объекта. Дополнительное выражение else
позволяет задать действия, которые выполняются, если объект не соответствует ни одному из значений:
val a = 30
when(a){
10 -> println("a = 10")
20 -> println("a = 20")
else -> println("неопределенное значение")
}
То есть в данном случае если переменная
a
равна 30, поэтому она не соответствует ни одному из значений в блоке when
. И соответственно будут выполняться инструкции из выражения else
.
var a = 10
when(a){
10 -> {
println("a = 10")
a *= 2
}
20 -> {
println("a = 20")
a *= 5
}
else -> { println("неопределенное значение")}
}
println(a)
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
При помощи открытого датасета в этом видео с нуля создаётся рекомендательная система музыки; разбирается, какие из наивных решений могут не сработать в реальных системах.
На примере технологий Одноклассников спикер рассказывает, как решаются ML-задачи в гетерогенных продакшенах, где необходимо использовать вместе Java и Python.
Мастер-класс будет интересен разработчикам, которым интересна тема машинного обучения, но они либо еще не погружались в нее, либо сделали самые первые шаги.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Встречайте годный контент
В этом ролике речь пойдёт об обеспечении безопасности веб-приложения при помощи Spring Security и будет продемонстрирована настройка цепочки фильтров безопасности.
Здесь показывается использование формы входа, Basic-аутентификации и применение OAuth 2.0/OpenID Connect.
Нереально полезно и информативно
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM