samba
samba

Reputation: 3091

Java - What could be an alternative to Google Guava Ranges?

I have a Map storing metric names and Ranges representing live periods for each metric. It was very convenient to store it this way:

private Map<String, Range<Long>> metricRanges = new HashMap<>();

When I needed to check if a given timestamp is in a Range, I just retrieved a Range for the key and then checked if the Range contains the timestamp.

Range<Long> rangeOfDates = metricRanges.get(key);
if (rangeOfDates != null && rangeOfDates.contains(timestamp)) {
    return true;
}

However I've faced a situation where it's necessary to use Google Guava library pre 14.0 which does not provide Range functionality. What could be an appropriate substitution for the data structure with Ranges that allows to check if a given value is in the Range?

Currently I'm thinking of creating a List<Long> ranges containing two values representing an upper and a lower bound. That will allow me to check if a timestamp is in the "range" like this:

private Map<String, List<Long>> metricRanges = new HashMap<>();
List<Long> rangeOfDates = metricRanges.get(key);
if (timestamp >= rangeOfDates.get(0) && timestamp <= rangeOfDates.get(1)) {
    return true;
}

Am I missing a more optional solution that could be achieved, for example with Guava pre 14.0?

UPD: just found something close to what I was looking for - a Range class from Apache commons-lang. Specifically the LongRange implementation.

Upvotes: 1

Views: 1708

Answers (2)

Grzegorz Rożniecki
Grzegorz Rożniecki

Reputation: 27995

If you're dealing with time ranges, you could benefit from Interval from ThreeTen-Extra, which is described as:

An immutable interval of time between two instants.

An interval represents the time on the time-line between two Instants. The class stores the start and end instants, with the start inclusive and the end exclusive. The end instant is always greater than or equal to the start instant.

Because Interval operates on Instants, not on longs, you have to decide whether it's worth using it in your case.

Upvotes: 0

OldCurmudgeon
OldCurmudgeon

Reputation: 65793

I would start with something like:

class Range<T extends Number> {
    private final T start;
    private final T end;

    Range(T start, T end) {
        this.start = start;
        this.end = end;
    }

    public boolean contains(Number n) {
        return start.longValue() <= n.longValue() && n.longValue() <= end.longValue();
    }
} 

Upvotes: 2

Related Questions