我有一个自定义范围(〜Collection
),它有2 Temporal
个边界(from
和to
)并且可以按时间枚举这两个边界之间的所有值使用给定的TemporalUnit incrementUnitType
递增。
private final Temporal_ from;
private final Temporal_ to;
private final TemporalUnit incrementUnitType; // For example Month, Day, Minute, ...
在其中,我需要实现一个contains方法,以检查迭代该范围是否包含特定值。例如,如果它包含3月8日。以下是我想写这种方法的方法:
public boolean contains(Temporal_ value) {
...
if (from.until(value, incrementUnitType) < 0
|| value.until(to, incrementUnitType) <= 0) {
return false; // Out of bounds
}
// This doesn't work because 1-MAR + 1 month doesn't include 8-MAR
return true;
}
这里进行了几次迭代:
在最后一种情况下,上面的代码将错误地返回8-MAR的true。通过执行for
循环并检查每个可能的值,我需要编写代码才能工作:
public boolean contains(Temporal_ value) {
...
if (from.until(value, incrementUnitType) < 0
|| value.until(to, incrementUnitType) <= 0) {
return false; // Out of bounds
}
// This works but it kills scalability
for (long i = 0; i < getSize(); i++) {
Temporal_ temporal = get(i);
if (value.equals(temporal)) {
return true;
}
}
return false;
}
这是一个可扩展性问题。有什么办法可以避免吗?
答案 0 :(得分:3)
您可以使用Temporal.until
方法获取结果。当它返回“两个时间段之间的完整单位数”(doc)时,您可以将此数字添加到from
并查看它是否等于该值,但这不会立即生效。
long wholeAmount = from.until(value, incrementUnitType)
return value.equals(from.plus(wholeAmount, incrementUnitType));
正如您所注意到的,问题是某些时间单位并不总是相同的持续时间(例如,一个月可能是28,29,30或31天)。 until
和plus
可能不一致(即temporal.until(temporal.plus(1,ChronoUnit.MONTHS),ChronoUnit.MONTHS)
可能为0,而我们添加了一个月)。
引用doc:
在某些情况下,未完全定义更改字段。例如,如果 目标对象是代表1月31日的日期,然后添加 一个月不清楚。在这种情况下,该领域是 负责解决结果。通常它会选择 上一个有效日期,也就是二月份的最后一个有效日期 这个例子。
这意味着我们还应该检查wholeAmount + 1
,以防整个金额被舍入。
// ... out of bound check
// ...
long wholeAmount = from.until(value, incrementUnitType)
return value.equals(from.plus(wholeAmount, incrementUnitType)) || value.equals(from.plus(wholeAmount + 1, incrementUnitType));
处理Temporal似乎很棘手所以我无法确定它是否适用于每个单元和每个时间(确保检查incrementUnitType是否与您的时间兼容)。可能有几个边缘情况需要测试。
答案 1 :(得分:2)
最有效的解决方案是每个增量单元的单独逻辑。
unserialize
,减去它们并检查它是否除以7 如果您可以避免使用toEpochDays()
作为输入类型,我会提醒您,因为它会使处理更加困难。一个选项,如果您必须使用它来调用输入上的Temporal
以允许逻辑在LocalDate.from(temporal)
内部工作。