Hoe kan ik een bereik in Java weergeven?

Stel dat een geheel getal binnen het bereik moet vallen: [0...2147483647]

Ik wil controleren of een integer-variabele binnen dit bereik valt. Ik weet dat het kan worden bereikt door een eenvoudige if-else-instructie, maar is er een efficiëntere manier om te controleren of het binnen het bereik valt?

Ik doe dit liever niet:

if (foo >= 0 && foo <= 2147483647) 
{
    // do something
}

Antwoord 1, autoriteit 100%

Apache Commons Lang heeft een Rangeklassevoor het doen van willekeurige bereiken.

Range<Integer> test = Range.between(1, 3);
System.out.println(test.contains(2));
System.out.println(test.contains(4));

Guave Rangeheeft een vergelijkbare API.

Als je alleen wilt controleren of een getal in een lange waarde of een int-waarde past, kun je het proberen via BigDecimal. Er zijn methoden voor longValueExacten intValueExactdie uitzonderingen genereren als de waarde te groot is voor die precisies.


Antwoord 2, autoriteit 43%

Je zou een klas kunnen maken om dit te vertegenwoordigen

public class Range
{
    private int low;
    private int high;
    public Range(int low, int high){
        this.low = low;
        this.high = high;
    }
    public boolean contains(int number){
        return (number >= low && number <= high);
    }
}

Voorbeeld van gebruik:

Range range = new Range(0, 2147483647);
if (range.contains(foo)) {
    //do something
}

Antwoord 3, autoriteit 31%

Ik weet dat dit een vrij oude vraag is, maar met Java 8’s Streams kun je een reeks ints krijgen zoals deze:

// gives an IntStream of integers from 0 through Integer.MAX_VALUE
IntStream.rangeClosed(0, Integer.MAX_VALUE); 

Dan kun je zoiets als dit doen:

if (IntStream.rangeClosed(0, Integer.MAX_VALUE).matchAny(n -> n == A)) {
    // do something
} else {
    // do something else 
}

Antwoord 4, autoriteit 14%

Als je veel intervallen controleert, raad ik je aan een intervalboomte gebruiken.


Antwoord 5, autoriteit 10%

Je zou java.time.temporal.ValueRangekunnen gebruiken die longaccepteert en ook zou werken met int:

int a = 2147;
//Use java 8 java.time.temporal.ValueRange. The range defined
//is inclusive of both min and max 
ValueRange range = ValueRange.of(0, 2147483647);
if(range.isValidValue(a)) {
    System.out.println("in range");
}else {
    System.out.println("not in range");
}

Antwoord 6, autoriteit 7%

Je krijgt een if-check, hoe efficiënt je deze niet-zo-intensieve berekening ook probeert te optimaliseren 🙂 Je kunt de bovengrens van het getal aftrekken en als het positief is, weet je dat je buiten bereik bent. Je kunt misschien wat booleaanse bit-shift-logica uitvoeren om erachter te komen en je kunt zelfs de stelling van Fermat gebruiken als je wilt (grapje 🙂 Maar het punt is “waarom” moet je deze vergelijking optimaliseren? Wat is het doel?


Antwoord 7, autoriteit 2%

Voor een reeks Comparablegebruik ik het volgende:

public class Range<T extends Comparable<T>> {
    /**
     * Include start, end in {@link Range}
     */
    public enum Inclusive {START,END,BOTH,NONE }
    /**
     * {@link Range} start and end values
     */
    private T start, end;
    private Inclusive inclusive;
    /**
     * Create a range with {@link Inclusive#START}
     * @param start
     *<br/> Not null safe
     * @param end
     *<br/> Not null safe
     */
    public Range(T start, T end) {  this(start, end, null); }
    /**
     * @param start
     *<br/> Not null safe
     * @param end
     *<br/> Not null safe
     *@param inclusive
     *<br/>If null {@link Inclusive#START} used
     */
    public Range(T start, T end, Inclusive inclusive) {
        if((start == null) || (end == null)) {
            throw new NullPointerException("Invalid null start / end value");
        }
        setInclusive(inclusive);
        if( isBigger(start, end) ) {
            this.start = end;   this.end   = start;
        }else {
            this.start = start;  this.end   = end;
        }
    }
    /**
     * Convenience method
     */
    public boolean isBigger(T t1, T t2) { return t1.compareTo(t2) > 0; }
    /**
     * Convenience method
     */
    public boolean isSmaller(T t1, T t2) { return t1.compareTo(t2) < 0; }
    /**
     * Check if this {@link Range} contains t
     *@param t
     *<br/>Not null safe
     *@return
     *false for any value of t, if this.start equals this.end
     */
    public boolean contains(T t) { return contains(t, inclusive); }
    /**
     * Check if this {@link Range} contains t
     *@param t
     *<br/>Not null safe
     *@param inclusive
     *<br/>If null {@link Range#inclusive} used
     *@return
     *false for any value of t, if this.start equals this.end
     */
    public boolean contains(T t, Inclusive inclusive) {
        if(t == null) {
            throw new NullPointerException("Invalid null value");
        }
        inclusive = (inclusive == null) ? this.inclusive : inclusive;
        switch (inclusive) {
            case NONE:
                return ( isBigger(t, start) && isSmaller(t, end) );
            case BOTH:
                return ( ! isBigger(start, t)  && ! isBigger(t, end) ) ;
            case START: default:
                return ( ! isBigger(start, t)  &&  isBigger(end, t) ) ;
            case END:
                return ( isBigger(t, start)  &&  ! isBigger(t, end) ) ;
        }
    }
    /**
     * Check if this {@link Range} contains other range
     * @return
     * false for any value of range, if this.start equals this.end
     */
    public boolean contains(Range<T> range) {
        return contains(range.start) && contains(range.end);
    }
    /**
     * Check if this {@link Range} intersects with other range
     * @return
     * false for any value of range, if this.start equals this.end
     */
    public boolean intersects(Range<T> range) {
        return contains(range.start) || contains(range.end);
    }
    /**
    * Get {@link #start}
    */
    public T getStart() { return start; }
    /**
    * Set {@link #start}
    * <br/>Not null safe
    * <br/>If start > end they are switched
    */
    public Range<T> setStart(T start) {
        if(start.compareTo(end)>0) {
            this.start = end;
            this.end  = start;
        }else {
            this.start = start;
        }
        return this;
    }
    /**
    * Get {@link #end}
    */
    public T getEnd() {  return end;  }
    /**
    * Set {@link #end}
    * <br/>Not null safe
    *  <br/>If start > end they are switched
    */
    public  Range<T> setEnd(T end) {
        if(start.compareTo(end)>0) {
            this.end  = start;
            this.start = end;
        }else {
            this.end = end;
        }
        return this;
    }
    /**
    * Get {@link #inclusive}
    */
    public Inclusive getInclusive() { return inclusive; }
    /**
    * Set {@link #inclusive}
    * @param inclusive
    *<br/>If null {@link Inclusive#START} used
    */
    public  Range<T> setInclusive(Inclusive inclusive) {
        this.inclusive = (inclusive == null) ? Inclusive.START : inclusive;
        return this;
    }
}

(Dit is een ietwat verkorte versie. De volledige code is hier)


Antwoord 8

import java.util.Arrays;
class Soft{
    public static void main(String[] args){
        int[] nums=range(9, 12);
        System.out.println(Arrays.toString(nums));
    }
    static int[] range(int low, int high){
        int[] a=new int[high-low];
        for(int i=0,j=low;i<high-low;i++,j++){
            a[i]=j;
        }
        return a;
    }
}

Mijn code is vergelijkbaar met het bereik van Python`s 🙂


Antwoord 9

Als u de lente gebruikt, kunt u vertrouwen op org.springframework.data.domein die vrij compleet is, inclusief gebonden en ongebonden bereiken.

Other episodes