value
があるとします。通常は、これを範囲にクランプします。ここでは範囲[0..1]
。つまり、範囲の開始より下の場合は、範囲の開始まで増やし、範囲の終わりより上で、範囲の終わりまで減らします。
clampedValue = Math.max(0, Math.min(1, value));
範囲に固定するための組み込み機能はありますか?
別の回答で提供されている一般的なクランプ方法を見てみると、これにはプリミティブ型に関する boxing/unboxing の考慮事項があることに注意する価値があります。
public static <T extends Comparable<T>> T clamp(T val, T min, T max) {...}
float clampedValue = clamp(value, 0f, 1f);
これはFloat
ラッパークラスを使用し、3つのボックス操作、各パラメーターに1つ、返された型に1つのボックス解除操作を行います。
これを回避するには、長文を書くか、必要なタイプに非汎用関数を使用するだけです。
public static float clamp(float val, float min, float max) {
return Math.max(min, Math.min(max, val));
}
次に、必要なすべてのプリミティブ型に対して同一のメソッドでオーバーロードします。
範囲に固定するための組み込み機能はありますか?
いや.
バージョン21の時点で、 Guava には Ints.constrainToRange()
(および他のプリミティブの同等のメソッド)が含まれています。 リリースノート から:
min
およびmax
の値で定義された閉じた範囲に特定の値を制約するconstrainToRange([type] value, [type] min, [type] 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
などのプリミティブ型を使用する場合、この実装は3つのボックス操作と1つのボックス解除操作を実行します。
注: 。NETの回答 の移植版であるため、これをコミュニティWiki投稿にしました。
別のそれほどきれいではないが、可能な解決策は、三項演算子を使用することです。これは、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;