按照页面每一行的从左到右
* 示例
[{"leftSymbol":">=","leftNum":100,"relation":"无","rightSymbol":null,"rightNum":0},
{"leftSymbol":"<","leftNum":1000,"relation":"且","rightSymbol":">","rightNum":3}]
* 转换为 [100,1000);[1000,+无穷);(-无穷,100]
这是很重要的一步,过程太长,在第二大点里边说
除了要把json转为开闭区间外,还要考虑多种情况
1.比如上边的例子,用户只选择了 [100,1000)
但是我需要补齐 [100,1000);[1000,+无穷);(-无穷,100]
2.如果用户选择了不连续区间,我还要把中断的部分补齐
比如用户选择了[-无穷,100];(300,正无穷)
但是我需要返回[-无穷,100];(100,300];(300,正无穷)
3.还有比如第二点和第三点情况都存在的情况
用户选择了[1,100];[500,1000]
但是我需要返回(-无穷,1);(100,500);(1000,+无穷)
思路:
根据页面上用户可能发生的操作行为,假定他是正确的前提下
(比如他没有选择空区间 如<1 且 >2,或者他没有选择重复区间 比如第一行 >1 第二行又>2)
* 逻辑解析: * //1.第一种大的情况 左边是( [ * //1.1 左边是( [ relation是“无” * //1.2 左边是 ( [ relation是“且” * //1.3 左边是 ( [ relation是“或” * //2.第二种大情况 左边是 ) ] * //2.1 左边是 ) ] relation是“无” * //2.2 左边是 ) ] relation是“且” * //2.3 左边是 ) ] relation是“或”
Integer Double Float Long 都有各自的MAX_VALUE 和 MIN_VALUE
比如 Long.MIN_VALUE Long.MAX_VALUE
这段代码比较垃圾 我还没有优化
因为Integer Double Float Long
有共同点
extends Number implements Comparable
其实可以从这一点入手 然后用泛型 整合成一个方法
json转换为开闭区间之后
要和各自区间的最大值最小值比
如果已有区间的元素中最小值,比这个类型的最小值大,说明要补充区间
比如现在类型是Integer,区间最小值100,那就需要补充区间(Integer.MIN_VALUE,100)
具体100是开是闭,看具体情况
再映射为list实体,然后用java8排序(这是一个比较重要的思想,以后应该也会用到)
第一个数排序一致,就用第二个数排序
按照从大到小的顺序,每个元素的开头的值和上一个元素结尾的值做比较,不相等,就是有漏的,就在这添加一个区间,
至于区间的开闭,需要看上一个区间的右区间和下一个区间的左区间,取相反
比如上个区间(100,200) 下个区间是[300,500)
那补充过来的这个区间就是[200,300)
思路大致如上,直接上代码,注释写的挺清楚的
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* @Description: 分区设置 区间接收传输实体
* @Version 1.0
*/
@ApiModel("分区设置 区间接收传输实体")
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@Builder
public class Range {
@ApiModelProperty("第一个符号 > >= < <=")
String leftSymbol;
@ApiModelProperty("第一个数字")
T leftNum;
@ApiModelProperty("无 且 或")
String relation;
@ApiModelProperty("第二个符号 > >= < <=")
String rightSymbol;
@ApiModelProperty("第二个数字")
T rightNum;
public static void main(String[] args) throws JsonProcessingException {
Range one = Range.builder().leftSymbol(">=").leftNum(1).relation("且").rightSymbol("<").rightNum(100).build();
Range two = Range.builder().leftSymbol(">=").leftNum(100).relation("且").rightSymbol("<").rightNum(300).build();
List list = Arrays.asList(one,two);
//转json存到数据库
ObjectMapper objectMapper = new ObjectMapper();
String test = objectMapper.writeValueAsString(list);
System.out.println(test);
//从数据取出来json转List
List personList = objectMapper.readValue(test, new TypeReference>() {
});
System.out.println(personList.size());
}
/**
* 通过符号取开闭区间
*
* @param symbol
* @return
*/
public String parseSymbol(String symbol) {
if(StringUtils.isEmpty(symbol)){
return null;
}
switch (symbol) {
case ">":
return LEFT_OPEN;
case ">=":
return LEFT_CLOSE;
case "<":
return RIGHT_OPEN;
case "<=":
return RIGHT_CLOSE;
default:
return null;
}
}
public static final String LEFT_OPEN = "(";
public static final String LEFT_CLOSE = "[";
public static final String RIGHT_OPEN = ")";
public static final String RIGHT_CLOSE = "]";
// "(","["
public static final List left = Arrays.asList(">", ">=");
// ")","]"
public static final List right = Arrays.asList("<", "<=");
/**
* relation的三种情况 无 且 或
*/
public static final String NOT_HAVE = "无";
public static final String AND = "且";
public static final String OR = "或";
/**
* 用法:返回值为转换后的开闭区间 含“或”时 则返回分号;拼接的两个区间
*
* 逻辑解析:
* //1.第一种大的情况 左边是( [
* //1.1 左边是( [ relation是“无”
* //1.2 左边是 ( [ relation是“且”
* //1.3 左边是 ( [ relation是“或”
* //2.第二种大情况 左边是 ) ]
* //2.1 左边是 ) ] relation是“无”
* //2.2 左边是 ) ] relation是“且”
* //2.3 左边是 ) ] relation是“或”
*
* @param dbFieldType
* @return
*/
public String parse(DBFieldType dbFieldType) {
if (Objects.isNull(dbFieldType)) {
return null;
}
//1.第一种大的情况 左边是( [
if (left.contains(this.leftSymbol)) {
return returnLeft(dbFieldType);
} else if (right.contains(this.leftSymbol)) {
//2.第二种大情况 左边是 ) ]
return returnRight(dbFieldType);
}
return null;
}
/**
* //2.第二种大情况 左边是 ) ]
* //2.1 左边是 ) ] relation是“无”
* //2.2 左边是 ) ] relation是“且”
* //2.3 左边是 ) ] relation是“或”
*
* @param dbFieldType
* @return
*/
private String returnRight(DBFieldType dbFieldType) {
StringBuilder builder = new StringBuilder();
//通过> >=取开闭区间符号
String symbol = this.parseSymbol(this.leftSymbol);
if (StringUtils.isEmpty(symbol)) {
return null;
}
//取当前字段的最小值
Object min = dbFieldType.getMin();
//2.1 左边是 ) ] relation是“无”
if (NOT_HAVE.equals(this.relation)) {
builder.append(LEFT_OPEN).append(min).append(Constant.COMMA_SPLIT).append(this.leftNum).append(symbol);
} else if (AND.equals(this.relation)) {
//2.2 左边是 ) ] relation是“且”
//假定表达式校验通过之后才能执行这个解析方法 如果左边是)] 那右边肯定是([
String symbolRight = this.parseSymbol(this.rightSymbol);
if (StringUtils.isEmpty(symbolRight)) {
return null;
}
builder.append(symbolRight).append(rightNum).append(Constant.COMMA_SPLIT).append(this.leftNum).append(symbol);
} else if (OR.equals(this.relation)) {
//2.3 左边是 ) ] relation是“或”
//分开两个区间返回
//第一个区间
builder.append(LEFT_OPEN).append(min).append(Constant.COMMA_SPLIT).append(this.leftNum).append(symbol);
//第二个区间
String builderRight = builderRight(dbFieldType);
builder.append(Constant.SEMICOLON).append(builderRight);
}
return builder.toString();
}
/**
* //1.第一种大的情况 左边是( [
* //1.1 左边是( [ relation是“无”
* //1.2 左边是 ( [ relation是“且”
* //1.3 左边是 ( [ relation是“或”
*
* @param dbFieldType
* @return
*/
private String returnLeft(DBFieldType dbFieldType) {
StringBuilder builder = new StringBuilder();
//通过> >=取开闭区间符号
String symbol = this.parseSymbol(this.leftSymbol);
String symbolRight = this.parseSymbol(this.rightSymbol);
if (StringUtils.isEmpty(symbol)) {
return null;
}
//取当前字段类型的最大值
Object max = dbFieldType.getMax();
//1.1 左边是( [ relation是“无”
if (NOT_HAVE.equals(this.relation)) {
//取当前字段类型的最大值,开区间
builder.append(symbol).append(this.leftNum).append(Constant.COMMA_SPLIT).append(max).append(RIGHT_OPEN);
} else if (AND.equals(this.relation)) {
//1.2 左边是 ( [ relation是“且”
builder.append(symbol).append(this.leftNum).append(Constant.COMMA_SPLIT).append(this.rightNum).append(symbolRight);
} else if (OR.equals(this.relation)) {
//1.3 左边是 ( [ relation是“或”
//分开两个区间返回
//第一个区间
builder.append(symbol).append(this.leftNum).append(Constant.COMMA_SPLIT).append(max).append(RIGHT_OPEN);
//第二个区间
String builderRight = builderRight(dbFieldType);
builder.append(Constant.SEMICOLON).append(builderRight);
}
return builder.toString();
}
/**
* 处理第二个区间
*
* @param dbFieldType
* @return
*/
public String builderRight(DBFieldType dbFieldType) {
Object max = dbFieldType.getMax();
//第二个区间
StringBuilder builder2 = new StringBuilder();
//通过> >=取开闭区间符号
String symbol2 = this.parseSymbol(this.rightSymbol);
if (StringUtils.isEmpty(symbol2)) {
return null;
}
// 右边是 ( [
if (left.contains(this.rightSymbol)) {
builder2.append(symbol2).append(this.rightNum).append(Constant.COMMA_SPLIT).append(max).append(RIGHT_OPEN);
} else if (right.contains(this.rightSymbol)) {
//右边是 ) ]
Object min = dbFieldType.getMin();
builder2.append(LEFT_OPEN).append(min).append(Constant.COMMA_SPLIT).append(this.rightNum).append(symbol2);
}
return builder2.toString();
}
}
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.function.Consumer;
/**
* @Description: 范围区间工具类
* @Version 1.0
*/
@Slf4j
public class RangeParseUtil {
/**
* * 通过json串转开闭区间
* * 入参是json和字段类型
* * 返回是分号;隔开的开闭区间
* * 示例 [{"leftSymbol":">=","leftNum":100,"relation":"无","rightSymbol":null,"rightNum":0},{"leftSymbol":"<","leftNum":1000,"relation":"且","rightSymbol":">","rightNum":3}]
* * 转换为 [100,1000)
*
* @param rangeSelect json字符串
* @param columnType 数据库字段类型
* @return
*/
public static String getRangeParseUtil(String rangeSelect, String columnType) {
if (StringUtils.isEmpty(rangeSelect) || StringUtils.isEmpty(columnType)) {
return null;
}
//通过类型取字段最大值最小值
DBFieldType dbFieldType = DBFieldType.getDBFieldType(columnType);
ObjectMapper objectMapper = new ObjectMapper();
List list;
try {
list = objectMapper.readValue(rangeSelect, new TypeReference>() {
});
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (CollectionUtils.isEmpty(list)) {
return null;
}
//将json转换为开闭区间
List builderList = new ArrayList<>();
list.forEach(range -> {
//返回的可能是分号;隔开的两个区间
String parse = range.parse(dbFieldType);
if (StringUtils.isNotEmpty(parse)) {
String[] split = parse.split(Constant.SEMICOLON);
builderList.addAll(Arrays.asList(split));
}
});
if (CollectionUtils.isEmpty(builderList)) {
return null;
}
//取最大值 最小值 不在这个区间范围的 放在另一个区间 或者是另外两个区间
//类型不同 比较大小的方式不同
//每一组元素 [1,2] (3,4) [5,6) (7,8] 第一个符号和第一个逗号之间是最小数字 第一个逗号到倒数第二个是最大数字
//最后要对区间中断的情况处理
switch (dbFieldType) {
case INT:
compareInt(builderList);
break;
case LONG:
compareLong(builderList);
break;
case FLOAT:
compareFloat(builderList);
break;
case DOUBLE:
compareDouble(builderList);
break;
}
//转换成;拼接的数组返回
return String.join(Constant.SEMICOLON, builderList);
}
/**
* float类型处理
* 循环比较 找出最小的 和最大的 并且取出来最小最大分别是开区间还是闭区间 用于组合默认区间 默认区间可能有两个 头一个 尾一个
* * [最小值,1)
* * [1,100)
* * [101,300)
* * [300,最大值)
*
* @param builderList
*/
private static void compareFloat(List builderList) {
String leftSymbol = null;
String rightSymbol = null;
Float minThis = null;
Float maxThis = null;
//最后用于比较排序 从而补充间断区间的list
List> compareList = new ArrayList<>();
for (String expression : builderList) {
//当前符号
String currentLeftSymbol = expression.substring(0, 1);
String currentRightSymbol = expression.substring(expression.length() - 1, expression.length());
//第一个符号和第一个逗号之间是最小数字
Float minMid = Float.valueOf(expression.substring(1, expression.indexOf(Constant.COMMA_SPLIT)));
//空就赋值
if (minThis == null) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//跟最小值比谁大
if (minMid.compareTo(minThis) < 0) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//第一个逗号到倒数第二个是最大数字
Float maxMid = Float.valueOf(expression.substring(expression.indexOf(Constant.COMMA_SPLIT) + 1, expression.length() - 1));
//空就赋值
if (maxThis == null) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//跟最大值比谁大
if (maxMid.compareTo(maxThis) > 0) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//取当前的开闭区间符号去构建RangeCompare
Range compare = Range.builder().leftSymbol(currentLeftSymbol).leftNum(minMid)
.relation(Constant.COMMA_SPLIT)
.rightNum(maxMid).rightSymbol(currentRightSymbol).build();
compareList.add(compare);
}
//把所有区间最小值 和 这个字段类型的最小值比较 如果min 0) {
StringBuilder builder = new StringBuilder();
builder.append(Range.LEFT_OPEN).append(Float.MIN_VALUE).append(Constant.COMMA_SPLIT).append(minThis);
if (Range.LEFT_OPEN.equals(leftSymbol)) {
builder.append(Range.RIGHT_CLOSE);
} else if (Range.LEFT_CLOSE.equals(leftSymbol)) {
builder.append(Range.RIGHT_OPEN);
}
builderList.add(builder.toString());
}
//把所有区间最大值 和这个字段类型的最大值比较 如果max>maxThis 就还有一个更大的区间 区间范围是maxThis,max 至于开闭 要看rightSymbol rightSymbol为闭 则(maxThis,max) rightSymbol为开 则[maxThis,max)
if (maxThis.compareTo(Float.MAX_VALUE) < 0) {
StringBuilder builder = new StringBuilder();
if (Range.RIGHT_OPEN.equals(rightSymbol)) {
builder.append(Range.LEFT_CLOSE);
} else if (Range.RIGHT_CLOSE.equals(rightSymbol)) {
builder.append(Range.LEFT_OPEN);
}
builder.append(maxThis).append(Constant.COMMA_SPLIT).append(Float.MAX_VALUE).append(Range.RIGHT_OPEN);
builderList.add(builder.toString());
}
//补充中断区间
addFloat(compareList, builderList);
}
/**
*
* builderList 补充好了最大值区间和最小值区间
* compareList 没补充最大值区间 最小值区间
* compareList 查缺 查现有数据的中断区间
* addList 补漏 把compareList排序后发现中断的区间 放到addList中
* 最后builderList+addList 就是全集
*
* @param compareList
* @param builderList
*/
private static void addDouble(List> compareList, List builderList) {
//最大值最小值补充完后 整个list排序 看区间是否连续 不连续就补充区间
//先按照左边得数排序 左边数相等得时候 再按照右边的数排序
compareList.sort(Comparator.comparing(Range::getLeftNum).thenComparing(Range::getRightNum));
List addList = new ArrayList<>();
//有序list 每个元素的右区间beforeRight和下一个元素的左区间nextLeft比较,如果有区间beforeRight before = null;
for (Range compare : compareList) {
if (Objects.nonNull(before)) {
int i = before.getRightNum().compareTo(compare.getLeftNum());
//如果有区间beforeRight> compareList, List builderList) {
//最大值最小值补充完后 整个list排序 看区间是否连续 不连续就补充区间
//先按照左边得数排序 左边数相等得时候 再按照右边的数排序
compareList.sort(Comparator.comparing(Range::getLeftNum).thenComparing(Range::getRightNum));
List addList = new ArrayList<>();
//有序list 每个元素的右区间beforeRight和下一个元素的左区间nextLeft比较,如果有区间beforeRight before = null;
for (Range compare : compareList) {
if (Objects.nonNull(before)) {
int i = before.getRightNum().compareTo(compare.getLeftNum());
//如果有区间beforeRight> compareList, List builderList) {
//最大值最小值补充完后 整个list排序 看区间是否连续 不连续就补充区间
//先按照左边得数排序 左边数相等得时候 再按照右边的数排序
compareList.sort(Comparator.comparing(Range::getLeftNum).thenComparing(Range::getRightNum));
List addList = new ArrayList<>();
//有序list 每个元素的右区间beforeRight和下一个元素的左区间nextLeft比较,如果有区间beforeRight before = null;
for (Range compare : compareList) {
if (Objects.nonNull(before)) {
int i = before.getRightNum().compareTo(compare.getLeftNum());
//如果有区间beforeRight> compareList, List builderList) {
//最大值最小值补充完后 整个list排序 看区间是否连续 不连续就补充区间
//先按照左边得数排序 左边数相等得时候 再按照右边的数排序
compareList.sort(Comparator.comparing(Range::getLeftNum).thenComparing(Range::getRightNum));
List addList = new ArrayList<>();
//有序list 每个元素的右区间beforeRight和下一个元素的左区间nextLeft比较,如果有区间beforeRight before = null;
for (Range compare : compareList) {
if (Objects.nonNull(before)) {
int i = before.getRightNum().compareTo(compare.getLeftNum());
//如果有区间beforeRight builderList) {
String leftSymbol = null;
String rightSymbol = null;
Double minThis = null;
Double maxThis = null;
//最后用于比较排序 从而补充间断区间的list
List> compareList = new ArrayList<>();
for (String expression : builderList) {
//当前符号
String currentLeftSymbol = expression.substring(0, 1);
String currentRightSymbol = expression.substring(expression.length() - 1, expression.length());
//第一个符号和第一个逗号之间是最小数字
Double minMid = Double.valueOf(expression.substring(1, expression.indexOf(Constant.COMMA_SPLIT)));
//空就赋值
if (minThis == null) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//跟最小值比谁大
if (minMid.compareTo(minThis) < 0) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//第一个逗号到倒数第二个是最大数字
Double maxMid = Double.valueOf(expression.substring(expression.indexOf(Constant.COMMA_SPLIT) + 1, expression.length() - 1));
//空就赋值
if (maxThis == null) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//跟最大值比谁大
if (maxMid.compareTo(maxThis) > 0) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//取当前的开闭区间符号去构建RangeCompare
Range compare = Range.builder().leftSymbol(currentLeftSymbol).leftNum(minMid)
.relation(Constant.COMMA_SPLIT)
.rightNum(maxMid).rightSymbol(currentRightSymbol).build();
compareList.add(compare);
}
//把所有区间最小值 和 这个字段类型的最小值比较 如果min 0) {
StringBuilder builder = new StringBuilder();
builder.append(Range.LEFT_OPEN).append(Double.MIN_VALUE).append(Constant.COMMA_SPLIT).append(minThis);
if (Range.LEFT_OPEN.equals(leftSymbol)) {
builder.append(Range.RIGHT_CLOSE);
} else if (Range.LEFT_CLOSE.equals(leftSymbol)) {
builder.append(Range.RIGHT_OPEN);
}
builderList.add(builder.toString());
}
//把所有区间最大值 和这个字段类型的最大值比较 如果max>maxThis 就还有一个更大的区间 区间范围是maxThis,max 至于开闭 要看rightSymbol rightSymbol为闭 则(maxThis,max) rightSymbol为开 则[maxThis,max)
if (maxThis.compareTo(Double.MAX_VALUE) < 0) {
StringBuilder builder = new StringBuilder();
if (Range.RIGHT_OPEN.equals(rightSymbol)) {
builder.append(Range.LEFT_CLOSE);
} else if (Range.RIGHT_CLOSE.equals(rightSymbol)) {
builder.append(Range.LEFT_OPEN);
}
builder.append(maxThis).append(Constant.COMMA_SPLIT).append(Double.MAX_VALUE).append(Range.RIGHT_OPEN);
builderList.add(builder.toString());
}
//补充中断区间
addDouble(compareList, builderList);
}
/**
* int类型处理
* 循环比较 找出最小的 和最大的 并且取出来最小最大分别是开区间还是闭区间 用于组合默认区间 默认区间可能有两个 头一个 尾一个
* * [最小值,1)
* * [1,100)
* * [101,300)
* * [300,最大值)
*
* @param builderList
*/
private static void compareInt(List builderList) {
String leftSymbol = null;
String rightSymbol = null;
Integer minThis = null;
Integer maxThis = null;
//最后用于比较排序 从而补充间断区间的list
List> compareList = new ArrayList<>();
for (String expression : builderList) {
//当前开闭区间符号
String currentLeftSymbol = expression.substring(0, 1);
String currentRightSymbol = expression.substring(expression.length() - 1, expression.length());
//第一个符号和第一个逗号之间是最小数字
Integer minMid = Integer.valueOf(expression.substring(1, expression.indexOf(Constant.COMMA_SPLIT)));
//空就先赋值
if (minThis == null) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//跟最小值比谁大
if (minMid.compareTo(minThis) < 0) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//第一个逗号到倒数第二个是最大数字
Integer maxMid = Integer.valueOf(expression.substring(expression.indexOf(Constant.COMMA_SPLIT) + 1, expression.length() - 1));
//空就先赋值
if (maxThis == null) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//跟最大值比谁大
if (maxMid.compareTo(maxThis) > 0) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//取当前的开闭区间符号去构建RangeCompare
Range compare = Range.builder().leftSymbol(currentLeftSymbol).leftNum(minMid)
.relation(Constant.COMMA_SPLIT)
.rightNum(maxMid).rightSymbol(currentRightSymbol).build();
compareList.add(compare);
}
//把所有区间最小值 和 这个字段类型的最小值比较 如果min 0) {
StringBuilder builder = new StringBuilder();
builder.append(Range.LEFT_OPEN).append(Integer.MIN_VALUE).append(Constant.COMMA_SPLIT).append(minThis);
if (Range.LEFT_OPEN.equals(leftSymbol)) {
builder.append(Range.RIGHT_CLOSE);
} else if (Range.LEFT_CLOSE.equals(leftSymbol)) {
builder.append(Range.RIGHT_OPEN);
}
builderList.add(builder.toString());
}
//把所有区间最大值 和这个字段类型的最大值比较 如果max>maxThis 就还有一个更大的区间 区间范围是maxThis,max 至于开闭 要看rightSymbol rightSymbol为闭 则(maxThis,max) rightSymbol为开 则[maxThis,max)
if (maxThis.compareTo(Integer.MAX_VALUE) < 0) {
StringBuilder builder = new StringBuilder();
if (Range.RIGHT_OPEN.equals(rightSymbol)) {
builder.append(Range.LEFT_CLOSE);
} else if (Range.RIGHT_CLOSE.equals(rightSymbol)) {
builder.append(Range.LEFT_OPEN);
}
builder.append(maxThis).append(Constant.COMMA_SPLIT).append(Integer.MAX_VALUE).append(Range.RIGHT_OPEN);
builderList.add(builder.toString());
}
//补充中断区间
addInt(compareList, builderList);
}
/**
* Long类型处理
* 循环比较 找出最小的 和最大的 并且取出来最小最大分别是开区间还是闭区间 用于组合默认区间 默认区间可能有两个 头一个 尾一个
* * [最小值,1)
* * [1,100)
* * [101,300)
* * [300,最大值)
*
* @param builderList
*/
private static void compareLong(List builderList) {
String leftSymbol = null;
String rightSymbol = null;
Long minThis = null;
Long maxThis = null;
//最后用于比较排序 从而补充间断区间的list
List> compareList = new ArrayList<>();
for (String expression : builderList) {
//当前开闭区间符号
String currentLeftSymbol = expression.substring(0, 1);
String currentRightSymbol = expression.substring(expression.length() - 1, expression.length());
//第一个符号和第一个逗号之间是最小数字
Long minMid = Long.valueOf(expression.substring(1, expression.indexOf(Constant.COMMA_SPLIT)));
//空就先赋值
if (minThis == null) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//跟最小值比谁大
if (minMid.compareTo(minThis) < 0) {
minThis = minMid;
leftSymbol = currentLeftSymbol;
}
//第一个逗号到倒数第二个是最大数字
Long maxMid = Long.valueOf(expression.substring(expression.indexOf(Constant.COMMA_SPLIT) + 1, expression.length() - 1));
//空就先赋值
if (maxThis == null) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//跟最大值比谁大
if (maxMid.compareTo(maxThis) > 0) {
maxThis = maxMid;
rightSymbol = currentRightSymbol;
}
//取当前的开闭区间符号去构建RangeCompare
Range compare = Range.builder().leftSymbol(currentLeftSymbol).leftNum(minMid)
.relation(Constant.COMMA_SPLIT)
.rightNum(maxMid).rightSymbol(currentRightSymbol).build();
compareList.add(compare);
}
//把所有区间最小值 和 这个字段类型的最小值比较 如果min 0) {
StringBuilder builder = new StringBuilder();
builder.append(Range.LEFT_OPEN).append(Long.MIN_VALUE).append(Constant.COMMA_SPLIT).append(minThis);
if (Range.LEFT_OPEN.equals(leftSymbol)) {
builder.append(Range.RIGHT_CLOSE);
} else if (Range.LEFT_CLOSE.equals(leftSymbol)) {
builder.append(Range.RIGHT_OPEN);
}
builderList.add(builder.toString());
}
//把所有区间最大值 和这个字段类型的最大值比较 如果max>maxThis 就还有一个更大的区间 区间范围是maxThis,max 至于开闭 要看rightSymbol rightSymbol为闭 则(maxThis,max) rightSymbol为开 则[maxThis,max)
if (maxThis.compareTo(Long.MAX_VALUE) < 0) {
StringBuilder builder = new StringBuilder();
if (Range.RIGHT_OPEN.equals(rightSymbol)) {
builder.append(Range.LEFT_CLOSE);
} else if (Range.RIGHT_CLOSE.equals(rightSymbol)) {
builder.append(Range.LEFT_OPEN);
}
builder.append(maxThis).append(Constant.COMMA_SPLIT).append(Long.MAX_VALUE).append(Range.RIGHT_OPEN);
builderList.add(builder.toString());
}
//补充中断区间
addLong(compareList, builderList);
}
public static void main(String[] args) {
//String select = "[{\"leftSymbol\":\">=\",\"leftNum\":50,\"relation\":\"且\",\"rightSymbol\":\"<\",\"rightNum\":100},{\"leftSymbol\":\">=\",\"leftNum\":10,\"relation\":\"且\",\"rightSymbol\":\"<\",\"rightNum\":50},{\"leftSymbol\":\"<\",\"leftNum\":10,\"relation\":\"无\",\"rightSymbol\":null,\"rightNum\":null}]\n";
//String select = "[{\"leftSymbol\":\">=\",\"leftNum\":1,\"relation\":\"且\",\"rightSymbol\":\"<\",\"rightNum\":100},{\"leftSymbol\":\">=\",\"leftNum\":100,\"relation\":\"且\",\"rightSymbol\":\"<\",\"rightNum\":300}]";
String select = "[{\"leftSymbol\":\">=\",\"leftNum\":10,\"relation\":\"无\",\"rightSymbol\":null,\"rightNum\":null}]";
String bigint = getRangeParseUtil(select, "FLOAT");
System.out.println(bigint);
}
}