web-dev-qa-db-ja.com

Javaにはクランプ機能がありますか?

valueがあるとします。通常は、これを範囲にクランプします。ここでは範囲[0..1]。つまり、範囲の開始より下の場合は、範囲の開始まで増やし、範囲の終わりより上で、範囲の終わりまで減らします。

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

範囲に固定するための組み込み機能はありますか?

51
weston

別の回答で提供されている一般的なクランプ方法を見てみると、これにはプリミティブ型に関する 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));
}

次に、必要なすべてのプリミティブ型に対して同一のメソッドでオーバーロードします。

42
weston

範囲に固定するための組み込み機能はありますか?

いや.

154
Matt Ball

バージョン21の時点で、 Guava には Ints.constrainToRange() (および他のプリミティブの同等のメソッド)が含まれています。 リリースノート から:

minおよびmaxの値で定義された閉じた範囲に特定の値を制約するconstrainToRange([type] value, [type] min, [type] max)メソッドを追加しました。範囲内にある場合は値自体を返し、範囲より下にある場合はminを返し、範囲より上にある場合はmaxを返します。

17
dimo414

。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とは異なり、プリミティブ型はジェネリックでは許可されません。つまり、ボックス化/非ボックス化する必要があります。 intdoubleなどのプリミティブ型を使用する場合、この実装は3つのボックス操作と1つのボックス解除操作を実行します。

注: 。NETの回答 の移植版であるため、これをコミュニティWiki投稿にしました。

15
Adam Gent

別のそれほどきれいではないが、可能な解決策は、三項演算子を使用することです。これは、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;
2
HugoTeixeira