java自定义范围比较器

因为在大数据项目中遇到数据都在内存中的情况, 没有办法通过查询语句在载入数据的地方做过滤,所以利用guava 的rangeSet类做了一个自定义比较器.

适用场景:

       /**
     * 范围比较生成器, 支持自定义比较的数据类型, 自定义数据类型需要实现Comparable 接口
     *
     * @param gte 大于等于 great than equals
     * @param gt  大于
     * @param lte 小于等于
     * @param lt 小于
     * @param range  当范围为空的时候, 默认给的一个范围值
     * @param <C>
     * @return
     */
    private <C extends Comparable<?>> Range<C> getRange(C gte, C gt, C lte, C lt, Range<C> range) {
        //  大于等于 >=
        if (gt == null && gte != null) {
            // 小于 <
            if (lte == null && lt != null) {
                range = Range.closedOpen(gte, lt);
                // 小于等于 <=
            } else if (lt == null && lte != null) {
                range = Range.closed(gte, lte);
            } else {
                //大于等于某值 ,小于最大值
                range = Range.closedOpen(gte, range.upperEndpoint());
            }
            // 大于 >
        } else if (gte == null && gt != null) {
            // 小于 <
            if (lte == null && lt != null) {
                range = Range.open(gt, lt);
                // 小于等于 <=
            } else if (lt == null && lte != null) {
                range = Range.closedOpen(gt, lte);
            } else {
                //大于等于某值 ,小于最大值
                range = Range.closedOpen(gt, range.upperEndpoint());
            }
        } else {
            // 小于 <
            if (lte == null && lt != null) {
                range = Range.open(range.lowerEndpoint(), lt);
                // 小于等于 <=
            } else if (lt == null && lte != null) {
                range = Range.closedOpen(range.lowerEndpoint(), lte);
            } else {
                return range;
            }
        }
        return range;
    }

接着就可以用range的 contains方法来判断一个值是否在范围中了. 不仅支持常见的String,Integer,Date, 等数据类型, 还支持自定义类, 只要实现Comparable 接口就可以比较


guava如何处理开闭区间

通过上面的代码, 我们发现判断两边的开闭区间是一件很痛苦的事情,写了很多if…else…,
我们看看google聪明的工程师是如何做的…
//guava Range 源码处理开闭的方法

  1. Range 类的open, closeOpen等方法传入的参数其实是一个抽象父类Cut, 这个Cut有四个实现类, 分别表示了>,>= ,<,<= ,根据Range调用的方法不同, 最终初始化的子类也不一样, 每个子类都会重写父类Cut的lessThan方法, lessThan方法对比较的边界做了不一样的区分.
  //举例: closeOpen 和openClose 虽然传的都是cut类,
  //但是cut类有4个内部类,分别代表四种不同的情况,
  //等我们调用Range.contains的时候,我们用每一个具体实现类的比较方法
  public static <C extends Comparable<?>> Range<C> closedOpen(
      C lower, C upper) {
    return create(Cut.belowValue(lower), Cut.belowValue(upper));
  }

  public static <C extends Comparable<?>> Range<C> openClosed(
      C lower, C upper) {
    return create(Cut.aboveValue(lower), Cut.aboveValue(upper));
  }

总结:代码虽然简单, 但是却发现在google聪明的工程师们确实做到了面向对象,四种不同的情况,分成了4个不同的类. 拓宽了我们的思路.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值