1.区间列表求交集、差集、并集
比如区间列表{[10-100],[120-200]} 减去 {[50-60],[65-70],[75-80]} 用代码怎么实现?
已经写了两个区间之间的计算方法,代码如下,但是列表相减会出现问题,有没有大佬解决过类型问题?
考虑过区间转成数组,但是由于范围可能会很大,所以排除此种解决方法。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MsCrowdConditionDO {
/**
* 表名
*/
private String tableName;
/**
* 字段名
*/
private String fieldName;
/**
* 字段值起始
*/
private String startValue;
/**
* 字段值结束
*/
private String endValue;
}
/**
* [两个区间值进行合并]
*
* @param rangeOne
* @param rangeTwo
* @param relation
* @return java.util.List<MsCrowdAssembleDO>
* @author LPF
* @date 2019-08-23 15:52
*/
public List<MsCrowdConditionDO> mergeRange(MsCrowdConditionDO rangeOne, MsCrowdConditionDO rangeTwo, Integer relation, String fieldName) {
Integer minStartValue = Integer.MIN_VALUE;
Integer maxEndValue = Integer.MAX_VALUE;
if (ObjectUtils.isEmpty(rangeOne)) {
rangeOne = new MsCrowdConditionDO("", fieldName, minStartValue.toString(), maxEndValue.toString());
}
if (ObjectUtils.isEmpty(rangeTwo)) {
rangeTwo = new MsCrowdConditionDO("", fieldName, minStartValue.toString(), maxEndValue.toString());
}
if (ObjectUtils.isEmpty(rangeOne.getStartValue())) {
rangeOne.setStartValue(minStartValue.toString());
}
if (ObjectUtils.isEmpty(rangeTwo.getStartValue())) {
rangeTwo.setStartValue(minStartValue.toString());
}
if (ObjectUtils.isEmpty(rangeOne.getEndValue())) {
rangeOne.setEndValue(minStartValue.toString());
}
if (ObjectUtils.isEmpty(rangeTwo.getEndValue())) {
rangeTwo.setEndValue(minStartValue.toString());
}
List<MsCrowdConditionDO> list = new ArrayList<>();
//并集
if (relation.equals(RelationEnum.MERGE.getCode())) {
list.add(rangeOne);
list.add(rangeTwo);
}
//相减
if (relation.equals(RelationEnum.SUBTRACTING.getCode())) {
//区间1 包含于区间2中 相减为空
// if (Double.valueOf(rangeOne.getStartValue()) >= Double.valueOf(rangeTwo.getStartValue())
// && Double.valueOf(rangeOne.getEndValue()) <= Double.valueOf(rangeTwo.getEndValue())) {
// }
//区间2的开始值 在区间1范围内
if (Double.valueOf(rangeOne.getStartValue()) < Double.valueOf(rangeTwo.getStartValue())
&& Double.valueOf(rangeTwo.getStartValue()) < Double.valueOf(rangeOne.getEndValue())) {
list.add(new MsCrowdConditionDO("", fieldName, rangeOne.getStartValue(), rangeTwo.getStartValue()));
}
//区间2的结束值 在区间1范围内
if (Double.valueOf(rangeOne.getEndValue()) > Double.valueOf(rangeTwo.getEndValue())
&& Double.valueOf(rangeTwo.getEndValue()) > Double.valueOf(rangeOne.getStartValue())) {
list.add(new MsCrowdConditionDO("", fieldName, rangeTwo.getEndValue(), rangeOne.getEndValue()));
}
//区间2的结束值小于区间1的开始值,或者区间2的开始值大于区间1的结束值,则相减为区间1本身
if (Double.valueOf(rangeTwo.getEndValue()) < Double.valueOf(rangeOne.getStartValue())
|| Double.valueOf(rangeTwo.getStartValue()) > Double.valueOf(rangeOne.getEndValue())) {
list.add(rangeOne);
}
}
//交集
if (relation.equals(RelationEnum.INTERSECTION.getCode())) {
String startValue = String.valueOf(Math.max(Double.valueOf(rangeOne.getStartValue()), Double.valueOf(rangeTwo.getStartValue())));
String endValue = String.valueOf(Math.min(Double.valueOf(rangeOne.getEndValue()), Double.valueOf(rangeTwo.getEndValue())));
if (Double.valueOf(startValue) <= Double.valueOf(endValue)) {
list.add(new MsCrowdConditionDO("", fieldName, startValue, endValue));
}
}
//排除
if (relation.equals(RelationEnum.RULE_OUT.getCode())) {
//并集
List<MsCrowdConditionDO> allList = new ArrayList<>();
allList.add(rangeOne);
allList.add(rangeTwo);
//交集
List<MsCrowdConditionDO> sameList = new ArrayList<>();
String startValue = String.valueOf(Math.max(Double.valueOf(rangeOne.getStartValue()), Double.valueOf(rangeTwo.getStartValue())));
String endValue = String.valueOf(Math.min(Double.valueOf(rangeOne.getEndValue()), Double.valueOf(rangeTwo.getEndValue())));
if (Double.valueOf(startValue) <= Double.valueOf(endValue)) {
sameList.add(new MsCrowdConditionDO("", fieldName, startValue, endValue));
}
//并集减去交集
if (!ObjectUtils.isEmpty(allList)) {
if (ObjectUtils.isEmpty(sameList)) {
return allList;
}
for (MsCrowdConditionDO mcOne : allList) {
for (MsCrowdConditionDO mcTwo : sameList) {
//区间2的开始值 在区间1范围内
if (Double.valueOf(mcOne.getStartValue()) < Double.valueOf(mcTwo.getStartValue())
&& Double.valueOf(mcTwo.getStartValue()) < Double.valueOf(mcOne.getEndValue())) {
list.add(new MsCrowdConditionDO("", fieldName, mcOne.getStartValue(), mcTwo.getStartValue()));
}
//区间2的结束值 在区间1范围内
if (Double.valueOf(mcOne.getEndValue()) > Double.valueOf(mcTwo.getEndValue())
&& Double.valueOf(mcTwo.getEndValue()) > Double.valueOf(mcOne.getStartValue())) {
list.add(new MsCrowdConditionDO("", fieldName, mcTwo.getEndValue(), mcOne.getEndValue()));
}
//区间2的结束值小于区间1的开始值,或者区间2的开始值大于区间1的结束值,则相减为区间1本身
if (Double.valueOf(mcTwo.getEndValue()) < Double.valueOf(mcOne.getStartValue())
|| Double.valueOf(mcTwo.getStartValue()) > Double.valueOf(mcOne.getEndValue())) {
list.add(mcOne);
}
}
}
}
}
return list;
}