How can I represent a range in Java?

Java

Java Problem Overview


Let's say an integer should be within the range: [0...2147483647]

I want to check whether an integer variable falls within this range. I know it can be accomplished by a simple if-else statement, but is there a more efficient way to check whether it's within the range?

I'd rather not do this:

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

Java Solutions


Solution 1 - Java

Apache Commons Lang has a Range class for doing arbitrary ranges.

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

Guava Range has similar API.

If you are just wanting to check if a number fits into a long value or an int value, you could try using it through BigDecimal. There are methods for longValueExact and intValueExact that throw exceptions if the value is too big for those precisions.

Solution 2 - Java

You could create a class to represent this

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

Sample usage:

Range range = new Range(0, 2147483647);

if (range.contains(foo)) {
    //do something
}

Solution 3 - Java

I know this is quite an old question, but with Java 8's Streams you can get a range of ints like this:

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

Then you can do something like this:

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

Solution 4 - Java

You could use java.time.temporal.ValueRange which accepts long and would also work with 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");
}

Solution 5 - Java

If you are checking against a lot of intervals, I suggest using an interval tree.

Solution 6 - Java

You will have an if-check no matter how efficient you try to optimize this not-so-intensive computation :) You can subtract the upper bound from the number and if it's positive you know you are out of range. You can perhaps perform some boolean bit-shift logic to figure it out and you can even use Fermat's theorem if you want (kidding :) But the point is "why" do you need to optimize this comparison? What's the purpose?

Solution 7 - Java

For a range of Comparable I use the following :

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

(This is a somewhat shorted version. The full code is available here )

Solution 8 - Java

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;

    }
}

My code is similar to Python`s range :)

Solution 9 - Java

If you use Spring, you can rely on org.springframework.data.domain that is quite complete including bound and unbound ranges.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question황현정View Question on Stackoverflow
Solution 1 - JavapimasterView Answer on Stackoverflow
Solution 2 - JavaScArcher2View Answer on Stackoverflow
Solution 3 - JavaJeff PrattView Answer on Stackoverflow
Solution 4 - Javac0derView Answer on Stackoverflow
Solution 5 - JavatskuzzyView Answer on Stackoverflow
Solution 6 - JavaPhDView Answer on Stackoverflow
Solution 7 - Javac0derView Answer on Stackoverflow
Solution 8 - JavaHayk EminyanView Answer on Stackoverflow
Solution 9 - JavaFranco GView Answer on Stackoverflow