我有一个自定义范围(〜Collection
),它具有2个Temporal
界限(from
和to
),并且可以通过增加给定的TemporalUnit incrementUnitType
来枚举这2个界限之间的所有值。
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;
}
那是一个可扩展性问题。有什么办法可以避免这种情况吗?
最佳答案
您可以使用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日的日期,然后添加
一个月还不清楚。在这种情况下,该字段为
负责解决结果。通常,它将选择
上一个有效日期,这是2月的最后一个有效日期
这个例子。
这意味着我们也应该检查
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似乎很棘手,因此我无法确定它是否适用于每个单位和每个时态(请确保检查递增单位类型是否与您的时态兼容)。可能有几种边缘情况应该进行测试。