How to Represent a Range in Java

What is the best way to represent all numbers in a given range? (some restrictions)

I once made a collection class that might be of interest to your problem.

It acts as Set<Long>, but it uses a very efficient internal representation with a good space/time tradeoff.

The key idea is to store consecutive ranges, more preceisely, the numbers where the function "contains" changes value. In the worst case the size is proportional to number of elements, which happens when elements represent a checkerboard (1, 3, 5, 7, 9 etc.), but even in that case, it's still just N. Empty and full set have constant size 1. Range 10000-30000 has a size of 2 instead of 20000, etc. Otherwise, ranges are merged and splitted dynamically when adding/removing values.

The class supports standard set operations such as intesection, union etc. In my experience it has worked great, but I probably didn't have as much requirements as you do. In practice, the number of "delta points" is still limited by java's Integer.MAX_VALUE, but it's reasonably straightforward to extend it to Long.MAX_VALUE or even BigInteger.

To address your problem, you should observe the patterns in your data. Is the pattern random or not? Are the values localized? Etc. Different usages call for different data structures and algorithms with different trade-offs. If you're just starting, take a look at HashSet, TreeSet or collections in Google Guava project to get you going, then look for the patterns in your data. There are also some probabilistic structures such as Bloom filters that you might find useful. Ultimately, the patterns you observe in your actual data will give you the best answer.

How to have a range of numbers in an if/else statement Java

If you want to test if number is between some values use logical operator AND for if statements like:

if(points>=40 && points <=45)

To get more clarity I would suggest you to make a control inversion like this:

    int grade;
if(points >49){
grade=5;
}else if(points >44){
grade=4;
}else if(points >39){
grade=3;
}else if(points >34){
grade=2;
}else if(points >29){
grade=1;
}else{
grade=0;

}
System.out.println("Gr: "+grade); //grade=0 = not passed

Using kind of range in Java Enum

The numbers 5 and 100 are two different values, so storing one value won't work here.

But it's easy enough to define two values in the enum, a low and a high value. For those where the range is just one, set both high and low to the same value.

enum SampleEnum {
A(1),
B(2),
C(3),
D(4),
E(5, 100);

private SampleEnum(int value){
this.low = value;
this.high = value;
}
private SampleEnum(int low, int high) {
this.low = low;
this.high = high;
}

private final int low;
private final int high;
}

How to represent TCP port range in Java (16 bit)

You just use a normal int in your program to store the port. When you want to send the int on the wire as a 16-bit value you simply cast it to a short. This just discards the high-order 16-bits (which you weren't using anyway) and the low-order 16-bits are are left unchanged. Example:

public byte[] encode() {
final int MESSAGE_SIZE = 10;
int portValue = 54321;
Bytebuffer buffer = ByteBuffer.allocate(MESSAGE_SIZE);
buffer.putInt(someInt);
buffer.putShort((short) portValue);
buffer.putInt(someOtherInt);
return buffer.array();
}

From Narrowing Primitive Conversions:

A narrowing conversion of a signed integer to an integral type T
simply discards all but the n lowest order bits, where n is the number
of bits used to represent type T.

making a range for data points in java

range is infinite if you want to include all fractional numbers otherwise you can do that manually.

for (int i=-x; i<=x; i++)
operate(i, y, z);

another solution for your problem is that you don't generate range.

you just store those values x y and z.

then, when you need to test if a number is in range you can do it easily with if statement.

what I mean that this a wrong way to design your solution. try to get values you want in another way. something like reverse engineering. then you test if those values are in range.

post your problem. then we can help you.


Code that generates numPointsA random numbers between -x and x:

Random random = new Random();
double start = -x;
double end = x;
for (int i=0;i<numPointsA;i++)
{
double ran = random.nextDouble();
double result = start + (ran * (end - start));
System.out.println(result);
}

Using switch statement with a range of value in each case?

after reading all the comments I didn't see anybody mention enhanced switch in which
you can have multiple values in one case like this ->

switch(value){
case 1,2,3,4:
//dosth
break;
case 7,9,10,23:
//dosth
break;
}

and since in your case, there is only one expression in every case, you can do the following without the need to break every case->

switch (value) {
case 1, 2, 3, 4 -> System.out.println("one of 1,2,3,4 matched");
case 7, 9, 10, 23 -> System.out.println("one of 7,9,10,23 matched");
}

this is one of the many added benefits with enhanced switches in java.

How are ranges defined in Java?

This line (and similar):

case copies >= 0 && copies <= 99:

Returns a compiler error since it gives a boolean but the compiler expects an int since copy is declared as int.

One way to solve this is using an array with the desired ranks, and have a switch statement for the index found:

public double calculateCopyPrice(int copies) {
int[] range = { 99, 499, 749, 1000 };
double copyPrice = 0;
int index = -1;
for (int i = 0; i < range.length; i++) {
if (range[i] >= copies) {
index = i;
break;
}
}
switch (index) {
case 0: copyPrice = 0.30; break;
case 1: copyPrice = 0.28; break;
case 2: copyPrice = 0.27; break;
case 3: copyPrice = 0.26; break;
default: copyPrice = 0.25; break;
}
//probably more logic here...
return copyPrice;
}

After some tests, I've found a more flexible solution using a TreeMap<Integer, Double> which allows you to have a specie of range (what you're looking for) and ease the search by using TreeMap#ceilingEntry:

//TreeMap to store the "ranges"
TreeMap<Integer, Double> theMap = new TreeMap<Integer, Double>();
//add the data
theMap.put(99, 0.3);
theMap.put(499, 0.28);
theMap.put(749, 0.27);
theMap.put(1000, 0.26);
//the "default" value for max entries
theMap.put(Integer.MAX_VALUE, 0.25);
//testing the solution
Double ex1 = theMap.ceilingEntry(50).getValue();
Double ex2 = theMap.ceilingEntry(500).getValue();
Double ex3 = theMap.ceilingEntry(5000).getValue();
Double ex4 = theMap.ceilingEntry(100).getValue();
System.out.println(ex1);
System.out.println(ex2);
System.out.println(ex3);
System.out.println(ex4);


Related Topics



Leave a reply



Submit