У java есть функция зажима?

Предположим, у меня есть valueЯ обычно делаю это, чтобы "зажать" это в диапазоне, здесь диапазон [0..1], То есть, если он находится ниже начала диапазона, увеличьте его до начала диапазона, он выше конца диапазона, уменьшите до конца диапазона.

clampedValue = Math.max(0, Math.min(1, value));

Есть ли встроенная функция для фиксации диапазона?

7 ответов

Решение

Посмотрев на общий метод зажима, предложенный в другом ответе, стоит отметить, что это имеет свои соображения по поводу упаковки / распаковки примитивных типов.

public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...}

float clampedValue = clamp(value, 0f, 1f);

Это будет использовать Float класс-обертка, результатом которого являются 3 операции box, по одной для каждого параметра и 1 операция unbox для возвращаемого типа.

Чтобы избежать этого, я бы просто написал длинную руку или использовал неуниверсальную функцию для нужного вам типа:

public static float clamp(float val, float min, float max) {
    return Math.max(min, Math.min(max, val));
}

Затем просто перегрузите одинаковыми методами для каждого типа примитивов, который вам требуется.

Есть ли встроенная функция для фиксации диапазона?

Нет.

Начиная с версии 21, Guava включает Ints.constrainToRange()(и эквивалентные методы для других примитивов). Из примечаний к выпуску:

добавленной constrainToRange([type] value, [type] min, [type] max) методы, которые ограничивают данное значение закрытым диапазоном, определяемым min а также max ценности. Они возвращают само значение, если оно находится в пределах диапазона, min если это ниже диапазона и max если это выше диапазона.

Портировано из ответа.NET:

public static <T extends Comparable<T>> T clamp(T val, T min, T max) {
    if (val.compareTo(min) < 0) return min;
    else if (val.compareTo(max) > 0) return max;
    else return val;
}

Внимание: в отличие от.NET, примитивные типы не допускаются в обобщенных типах, что означает, что они должны быть упакованы / распакованы. При работе с примитивными типами, такими как int а также doubleэта реализация будет выполнять три операции с ящиками и одну операцию с ящиком.

Примечание: поскольку это порт ответа.NET, я сделал это вики-постом сообщества.

В Java 21 появится новый встроенный метод для этой цели .

Перегрузки предусмотрены для float, double, int и long.

Другое не очень красивое, но возможное решение - использовать троичный оператор, который является сокращением для if-then-else заявление.

Некоторые примеры:

// value must be between MIN_VALUE and MAX_VALUE
value = value > MAX_VALUE ? MAX_VALUE : value < MIN_VALUE ? MIN_VALUE : value;

// value must be between 0 and 10
value = value > 10 ? 10 : value < 0 ? 0 : value;

Это может быть не связано с вопросом, но если кто-то ищет ту же функцию в javafx или kotlin, что и я, вот они:

javafx:

      Utils.clamp(min, value, max)

котлин:

      value.coerceIn(min, max)
Другие вопросы по тегам