Math.min: примеры (JAVA)

Примеры использования Math.min в Java
Раздел: Математические операции
Math.min(int a, int b): int

Описание функции Math.min()

Метод Math.min() в Java предназначен для получения меньшего из двух числовых значений. Существует несколько перегрузок метода для примитивных типов: int, long, float и double. Каждая перегрузка принимает ровно два аргумента одного примитивного типа и возвращает значение того же типа.

Перечень сигнатур в стандартной библиотеке Java:

  • public static int Math.min(int a, int b)
  • public static long Math.min(long a, long b)
  • public static float Math.min(float a, float b)
  • public static double Math.min(double a, double b)

Поведение и особенности возвращаемых значений:

  • Для целых типов (int, long) возвращается числовое значение меньшего аргумента по стандартному порядку целых чисел.
  • Для плавающей точки (float, double) учитывается поведение IEEE 754: если один из аргументов является NaN, результатом будет NaN. При сравнении -0.0 и +0.0 возвращается -0.0 (меньшее по представлению знака). Бесконечности (Double.NEGATIVE_INFINITY и Double.POSITIVE_INFINITY) сравниваются по обычному упорядочению чисел.
  • Нельзя передать более двух аргументов в одну вызовную форму Math.min; для поиска минимума в массиве или коллекции применяются циклы, потоки или утилитные методы.
  • При использовании обёрток (Integer, Long и т. п.) возможна распаковка (unboxing). Если ссылка равна null, возникнет NullPointerException во время выполнения.

Типичные сферы применения: вычисление минимального значения между двумя переменными (например, ограничение размера, сравнение результатов вычислений), реализация операции «clamp» в сочетании с Math.max, упрощение выражений с ветвлением для выбора меньшего числа.

Короткие примеры вызовов

Примеры для разных перегрузок и ситуаций.

Пример для int:

int a = Math.min(5, 10);
System.out.println(a);
5

Пример для long:

long x = Math.min(100L, 20L);
System.out.println(x);
20

Пример для double с NaN:

double d = Math.min(Double.NaN, 1.0);
System.out.println(d);
NaN

Пример для double с нулями разного знака:

double z = Math.min(-0.0, +0.0);
System.out.println(z);
-0.0

Поиск минимума в массиве (через цикл):

int[] arr = {7, 3, 9, 1, 5};
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
    min = Math.min(min, arr[i]);
}
System.out.println(min);
1

Поиск минимума в примитивном потоке:

import java.util.Arrays;
int minStream = Arrays.stream(arr).min().orElse(Integer.MAX_VALUE);
System.out.println(minStream);
1

Похожие методы на Java и их отличия

  • Math.max() - зеркальная по смыслу функция для получения большего из двух значений.
  • StrictMath.min() - аналог Math.min с более строгим требованием воспроизводимости и возможным иным поведением реализации, но по большей части результаты совпадают с Math.min.
  • Integer.min() и Long.min() - статические методы в классах-обёртках (начиная с Java 8). По сути выполняют то же, что Math.min для соответствующих примитивов, иногда используются ради читабельности или удобства при работе с обёртками.
  • Collections.min() - для коллекций объектов, использует Comparable или передаваемый Comparator, удобен при работе с объектными типами и списками.
  • Stream.min() - метод потоков для получения наименьшего элемента коллекции по заданному компаратору; предпочтителен для декларативной обработки коллекций.

Выбор: для двух примитивов - Math.min или соответствующая обёртка (Integer.min и т. п.). Для коллекций объектов - Collections.min или Stream.min. Если требуется переносимость и строгое соответствие IEEE 754 - рассмотреть StrictMath (редкие случаи).

Аналоги в других языках и отличия

Краткое сравнение с синтаксисом и поведением в популярных языках.

  • PHP: min(). Поддерживает список аргументов или массивы. При сравнении чисел поведение простое, при смешении типов возможны преобразования. Пример:
    echo min(5, 3);
    3
  • JavaScript: Math.min(...values). Может принять любое количество аргументов; пустой вызов возвращает Infinity. При передачe массива часто используется спред-оператор. Пример:
    console.log(Math.min(10, 2));
    console.log(Math.min());
    console.log(Math.min(...[4,1,9]));
    2
    Infinity
    1
    Отличие: JavaScript поддерживает вариадик и возвращает +Infinity для пустого списка.
  • Python: min(). Поддерживает произвольное количество аргументов и iterable; можно передать ключевую функцию key. Пример:
    print(min(5, 2))
    print(min([3,7,1]))
    2
    1
  • SQL: функция LEAST(a, b, ...) (в большинстве диалектов) возвращает минимальное значение среди аргументов; поведение с NULL зависит от СУБД (часто NULL доминирует). Пример (PostgreSQL):
    SELECT LEAST(5, 2, 9);
    2
  • C#: Math.Min(a, b) (перегрузки для разных типов). Поведение схоже с Java для целых и плавающих типов; при работе с NULL для Nullable<T> требуется проверка. Пример:
    Console.WriteLine(Math.Min(5, 8));
    5
  • Lua: math.min() - принимает переменное число аргументов, возвращает минимальный; при отсутствии аргументов возвращает +inf. Пример:
    print(math.min(3, 1, 7))
    1
  • Go: пакет math содержит math.Min(x, y float64) для float64. Для целых типов нет встроенной функции в стандартной библиотеке - обычно пишут простую функцию. Пример:
    package main
    import ("fmt"; "math")
    func main(){ fmt.Println(math.Min(3.0, 5.0)) }
    3
  • Kotlin: kotlin.math.min(a, b) с перегрузками; при использовании JVM обычно делегирует к соответствующим Java-методам для примитивов. Пример:
    println(kotlin.math.min(4, 2))
    2

Отличия от Java: вариативность аргументов в некоторых языках (JavaScript, Python, Lua) и особенности работы с NaN/NULL (SQL/JS/PHP) или отсутствием версий для целых типов (Go).

Типичные ошибки и примеры

  • Ожидание работы с более чем двумя аргументами в одном вызове Math.min - в Java такой перегрузки нет. Частая ошибка - попытка написать Math.min(a, b, c), что не скомпилируется.
  • Использование обёрток с null, приводящее к NullPointerException.
  • Недооценка поведения с NaN и знаковыми нулями у плавающей точки.
  • Ожидание автоматической работы с коллекциями - требуется явно итерировать или применять утилиты.

Примеры ошибок.

Попытка передать три аргумента:

// Компиляция не пройдёт
int m = Math.min(1, 2, 3);
Ошибка компиляции: подходящая перегрузка метода Math.min(int,int) не найдена

Null при использовании обёрток:

Integer ai = null;
Integer bi = 5;
System.out.println(Math.min(ai, bi));
Exception in thread "main" java.lang.NullPointerException
 (возникает при попытке unboxing ai)

Неправильное предположение о NaN:

double r = Math.min(Double.NaN, 2.0);
System.out.println(r);
System.out.println(Double.isNaN(r));
NaN
true

Изменения в реализации и API

Сам метод Math.min() как набор перегрузок для примитивов не претерпел значительных изменений в последних версиях Java. Основные связанные изменения исторически:

  • Начиная с Java 8 появились методы Integer.min() и Long.min() в классах-обёртках, что дало альтернативный синтаксис.
  • StrictMath предоставляет соответствующие реализации для тех случаев, когда требуется строго воспроизводимое поведение между платформами.

Новых перегрузок для других типов (например, для BigInteger) в стандартной библиотеке не добавлялось; для таких типов применяются отдельные методы.

Расширенные и нечастые сценарии применения

Подробные примеры с пояснениями.

1) Комбинация Math.min и Math.max для реализации clamp (ограничение значения в диапазоне):

Пример java
int clamp(int value, int min, int max) {
    return Math.min(max, Math.max(min, value));
}
System.out.println(clamp(10, 0, 5));
System.out.println(clamp(-5, 0, 5));
System.out.println(clamp(3, 0, 5));
5
0
3

Пояснение: сначала ограничение снизу через Math.max, затем сверху через Math.min.

2) Наименьший элемент в коллекции объектов с использованием Comparator:

Пример java
import java.util.*;
class Item { int v; Item(int v){this.v=v;} public String toString(){return String.valueOf(v);} }
List list = Arrays.asList(new Item(5), new Item(2), new Item(8));
Item minItem = Collections.min(list, Comparator.comparingInt(i -> i.v));
System.out.println(minItem);
2

3) Минимум в многопоточной среде - агрегация по частичным результатам (используется при MapReduce-подходе):

Пример java
// Псевдокод: каждый поток вычисляет локальный минимум, затем общий минимум
int globalMin = Integer.MAX_VALUE;
for (int local : localResults) {
    globalMin = Math.min(globalMin, local);
}
System.out.println(globalMin);
(выпечатка минимального значения среди localResults)

4) Обработка NaN при вычислении минимума: иногда требуется игнорировать NaN и выбирать число. Пример обхода:

Пример java
double safeMin(double a, double b) {
    if (Double.isNaN(a)) return b;
    if (Double.isNaN(b)) return a;
    return Math.min(a, b);
}
System.out.println(safeMin(Double.NaN, 2.0));
System.out.println(safeMin(3.0, Double.NaN));
System.out.println(safeMin(Double.NaN, Double.NaN));
2.0
3.0
NaN

5) Использование в функциональном стиле с потоками (Stream API) для массивов примитивов:

Пример java
int[] nums = {4, 2, 9, 1};
int min = Arrays.stream(nums).reduce(Integer::min).orElse(Integer.MAX_VALUE);
System.out.println(min);
1

6) Минимум для BigInteger или BigDecimal - собственная реализация с использованием compareTo:

Пример java
import java.math.BigInteger;
BigInteger a = new BigInteger("100000000000000000");
BigInteger b = new BigInteger("99999999999999999");
BigInteger min = a.compareTo(b) <= 0 ? a : b;
System.out.println(min);
99999999999999999

7) Контроль влияния знака нуля при сравнениях чисел с плавающей точкой (критично в численных алгоритмах):

Пример java
double a = -0.0;
double b = +0.0;
double m = Math.min(a, b);
System.out.println(m);
System.out.println(1.0 / m); // проверка знака нуля: -Infinity для -0.0
-0.0
-Infinity

В указанных примерах демонстрируется как типичные, так и редкие сценарии применения Math.min в реальных задачах: клэмпинг, агрегация, работа с NaN, численные тонкости и работа с объектными типами.

джава Math.min function comments

En
Math.min Возвращает меньшее из двух значений