У 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)