it-swarm.com.de

Hat Java eine Klemmfunktion?

Angenommen, ich habe ein value, ich mache das normalerweise, um es auf einen Bereich zu "klemmen", hier den Bereich [0..1]. Das heißt, wenn es unterhalb des Bereichsanfangs liegt, erhöhen Sie es bis zum Bereichsanfang, über dem Bereichsende, reduzieren Sie es bis zum Bereichsende.

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

Gibt es eine eingebaute Funktion zum Klemmen an einen Bereich?

51
weston

In Anbetracht der allgemeinen Klemmmethode, die in einer anderen Antwort angeboten wird, ist anzumerken, dass dies Boxen/Unboxen Überlegungen für primitive Typen enthält.

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

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

Dies verwendet die Wrapper-Klasse Float, was zu 3 Box-Operationen führt, eine für jeden Parameter und eine Unbox-Operation für den zurückgegebenen Typ.

Um dies zu vermeiden, bleibe ich einfach beim Schreiben mit der langen Hand oder verwende eine nicht generische Funktion für den gewünschten Typ:

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

Überladen Sie dann einfach mit identischen Methoden für jeden benötigten primitiven Typ.

42
weston

Gibt es eine eingebaute Funktion zum Klemmen an einen Bereich?

Nein.

154
Matt Ball

Ab Version 21 enthält GuavaInts.constrainToRange() (und entsprechende Methoden für die anderen Grundelemente). Aus dem Versionshinweise :

constrainToRange([type] value, [type] min, [type] max) Methoden hinzugefügt, die den angegebenen Wert auf den geschlossenen Bereich beschränken, der durch die Werte min und max definiert ist. Sie geben den Wert selbst zurück, wenn er innerhalb des Bereichs liegt, den Wert min, wenn er unterhalb des Bereichs liegt, und den Wert max, wenn er oberhalb des Bereichs liegt.

17
dimo414

Portiert von einer .NET-Antwort :

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;
}

Achtung: Im Gegensatz zu .NET sind primitive Typen in Generika nicht zulässig, dh, sie müssen mit oder ohne Box versehen sein. Wenn Sie mit primitiven Typen wie int und double arbeiten, führt diese Implementierung drei Box-Operationen und eine Unbox-Operation aus.

Hinweis: Da es sich um einen Port von der .NET-Antwort handelt , habe ich dies zu einem Community-Wiki-Beitrag gemacht.

15
Adam Gent

Eine andere nicht so schöne, aber mögliche Lösung ist die Verwendung des ternären Operators, eine Abkürzung für if-then-else Erklärung.

Einige Beispiele:

// 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