Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transform a Guava Range to a Different Type

How do I transform a given Guava Range of one type to a range of another type.

I expect a compose method similar to Predicates.compose. Take Integer and Long for example:

Range<Integer> intRange = Range.compose(Range.atLeast(10l),integerFromLongFunction);

I wrote the compose method:

    public static <F extends Comparable<F>, T extends Comparable<T>> Range<T> compose(Range<F> range,
        Function<F, T> function) {
    Range<T> result;
    if (range.hasUpperBound() && range.hasLowerBound()) {
        T upperEndpoint = function.apply(range.upperEndpoint());
        T lowerEndpoint = function.apply(range.lowerEndpoint());
        result = Range.range(lowerEndpoint, range.lowerBoundType(), upperEndpoint, range.upperBoundType());
    } else if (range.hasUpperBound()) {
        result = Range.upTo(function.apply(range.upperEndpoint()), range.upperBoundType());
    } else if (range.hasLowerBound()) {
        result = Range.downTo(function.apply(range.lowerEndpoint()), range.lowerBoundType());
    } else {
        result = Range.all();
    }
    return result;
}

with the Unit Test:

@Test
public void testLongRangeToInteger() {
    Integer inRange = 6;
    Integer outOfRange = 3;
    Range<Long> longRange = Range.atLeast(5l);
    assertTrue(longRange.apply(inRange.longValue()));
    assertFalse(longRange.apply(outOfRange.longValue()));

    Function<Long, Integer> function = integerFromLongFunction();
    Range<Integer> intRange = RangeExtended.compose(longRange, function);
    assertTrue(intRange.apply(inRange));
    assertFalse(intRange.apply(outOfRange));
}

public static Function<Long, Integer> integerFromLongFunction() {
    return new Function<Long, Integer>() {

        @Override
        public Integer apply(Long input) {
            return (input == null) ? null : input.intValue();
        }
    };
}

My current desire is actually to convert a Joda Duration to it's corresponding millis, but I wrote the example in Long/Integer for simplicity.

It seems that Guava would have this, but I can't find anywhere. I'm using v14, but looking at the latest v17 javadoc didn't expose anything.

like image 898
Aaron Roller Avatar asked Jan 02 '26 06:01

Aaron Roller


1 Answers

Still doesn't appear to be a handy conversion method in guava 31.1.

One simple implementation is this:

public static <T extends Comparable<?>, U extends Comparable<?>>
@Nonnull Range<U> toRangeType( 
    @Nonnull Range<T> t, 
    @Nonnull Function<T,U> map ) 
{
    Range<U> u;
    
    boolean hasLowerBound = t.hasLowerBound();
    boolean hasUpperBound = t.hasUpperBound();
    
    if ( hasLowerBound) {
        if ( hasUpperBound ) {
            u = Range.range(  
                    map.apply( t.lowerEndpoint()), t.lowerBoundType(), 
                    map.apply( t.upperEndpoint()), t.upperBoundType());
        }
        else {
            u = Range.downTo( map.apply( t.lowerEndpoint()), t.lowerBoundType());
        }
    }
    else {
        if ( hasUpperBound ) {
            u = Range.upTo( map.apply( t.upperEndpoint()), t.upperBoundType());
        }
        else {
            u = Range.all();
        }
    }
    
    return u;
}
like image 89
Andy Thomas Avatar answered Jan 05 '26 06:01

Andy Thomas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!