Java: Детерминированность
У методов в любом языке программирования есть фундаментальные свойства. Эти свойства помогают понять, как метод поведет себя в разных ситуациях, как его тестировать и где применять. Одним из таких свойств является детерминированность.
Детерминированный метод всегда возвращает один и тот же результат при одинаковых входных данных. Например, детерминированным можно назвать метод, который извлекает символ из строки по его позиции:
"wow".charAt(1); // 'o'
"wow".charAt(1); // 'o'
"hexlet".charAt(0); // 'h'
"hexlet".charAt(0); // 'h'Сколько бы раз мы ни вызывали charAt() с аргументом 1 для строки "wow", он всегда вернет 'o'. Результат зависит только от входных данных и не меняется от вызова к вызову.
Недетерминированные методы
К противоположному типу относятся недетерминированные методы. Они возвращают разные результаты при одинаковых входных данных или при их отсутствии (методы без аргументов). Хорошим примером служит метод, который возвращает случайное число:
// Метод, возвращающий случайное число
Math.random(); // 0.09856613113197676
Math.random(); // 0.8839904367241888У этого метода нет аргументов, но его результат каждый раз разный. Насколько он разный, не важно. Даже если хотя бы один вызов среди миллиона даст другой результат, метод считается недетерминированным.
Детерминированный: Недетерминированный:
"wow".charAt(1) → всегда 'o' Math.random() → 0.42
"wow".charAt(1) → всегда 'o' Math.random() → 0.91
"wow".charAt(1) → всегда 'o' Math.random() → 0.07Почему это важно
Детерминированность влияет на то, как мы работаем с методами.
- детерминированные методы легко тестировать и предсказывать;
- их проще оптимизировать и использовать повторно;
- недетерминированные методы сложнее проверять, потому что результат меняется.
Поэтому там, где это возможно, лучше стремиться к тому, чтобы метод оставался детерминированным.
Задание
Метод Math.random() возвращает случайное число от 0 до 1 с большим количеством знаков после запятой. Но в реальных задачах бывает нужно получать случайные целые числа. Реализуйте код, который печатает на экран случайное целое число от 0 до 10. Чтобы получить такое число, нужно умножить результат вызова Math.random() на 10 и преобразовать тип полученного числа из double в int.
// Преобразование в int
(int) 0.932342; // 0
(int) 8.123412; // 8Попробуйте решить это задание в одну строчку
Полезное
Java: Детерминированность
У методов в любом языке программирования есть фундаментальные свойства. Эти свойства помогают понять, как метод поведет себя в разных ситуациях, как его тестировать и где применять. Одним из таких свойств является детерминированность.
Детерминированный метод всегда возвращает один и тот же результат при одинаковых входных данных. Например, детерминированным можно назвать метод, который извлекает символ из строки по его позиции:
"wow".charAt(1); // 'o'
"wow".charAt(1); // 'o'
"hexlet".charAt(0); // 'h'
"hexlet".charAt(0); // 'h'Сколько бы раз мы ни вызывали charAt() с аргументом 1 для строки "wow", он всегда вернет 'o'. Результат зависит только от входных данных и не меняется от вызова к вызову.
Недетерминированные методы
К противоположному типу относятся недетерминированные методы. Они возвращают разные результаты при одинаковых входных данных или при их отсутствии (методы без аргументов). Хорошим примером служит метод, который возвращает случайное число:
// Метод, возвращающий случайное число
Math.random(); // 0.09856613113197676
Math.random(); // 0.8839904367241888У этого метода нет аргументов, но его результат каждый раз разный. Насколько он разный, не важно. Даже если хотя бы один вызов среди миллиона даст другой результат, метод считается недетерминированным.
Детерминированный: Недетерминированный:
"wow".charAt(1) → всегда 'o' Math.random() → 0.42
"wow".charAt(1) → всегда 'o' Math.random() → 0.91
"wow".charAt(1) → всегда 'o' Math.random() → 0.07Почему это важно
Детерминированность влияет на то, как мы работаем с методами.
- детерминированные методы легко тестировать и предсказывать;
- их проще оптимизировать и использовать повторно;
- недетерминированные методы сложнее проверять, потому что результат меняется.
Поэтому там, где это возможно, лучше стремиться к тому, чтобы метод оставался детерминированным.
Задание
Метод Math.random() возвращает случайное число от 0 до 1 с большим количеством знаков после запятой. Но в реальных задачах бывает нужно получать случайные целые числа. Реализуйте код, который печатает на экран случайное целое число от 0 до 10. Чтобы получить такое число, нужно умножить результат вызова Math.random() на 10 и преобразовать тип полученного числа из double в int.
// Преобразование в int
(int) 0.932342; // 0
(int) 8.123412; // 8Попробуйте решить это задание в одну строчку
Полезное
Ваше упражнение проверяется по этим тестам
import static org.assertj.core.api.Assertions.assertThat;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.stream.IntStream;
class AppTest {
public static void main(String[] args) {
IntStream.range(0, 10)
.forEach(
i -> {
App.main(null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
App.main(null);
var actual = Integer.parseInt(out.toString().trim());
System.out.println(actual);
assertThat(actual).isBetween(0, 10);
});
}
}Решение учителя откроется через:
20:00
