📄 timeseries.java
字号:
}
TimeSeriesDataItem overwritten = null;
TimeSeriesDataItem key = new TimeSeriesDataItem(period, value);
int index = Collections.binarySearch(this.data, key);
if (index >= 0) {
TimeSeriesDataItem existing
= (TimeSeriesDataItem) this.data.get(index);
overwritten = (TimeSeriesDataItem) existing.clone();
existing.setValue(value);
removeAgedItems(false); // remove old items if necessary, but
// don't notify anyone, because that
// happens next anyway...
fireSeriesChanged();
}
else {
this.data.add(-index - 1, new TimeSeriesDataItem(period, value));
// check if this addition will exceed the maximum item count...
if (getItemCount() > this.maximumItemCount) {
this.data.remove(0);
}
removeAgedItems(false); // remove old items if necessary, but
// don't notify anyone, because that
// happens next anyway...
fireSeriesChanged();
}
return overwritten;
}
/**
* Age items in the series. Ensure that the timespan from the youngest to
* the oldest record in the series does not exceed maximumItemAge time
* periods. Oldest items will be removed if required.
*
* @param notify controls whether or not a {@link SeriesChangeEvent} is
* sent to registered listeners IF any items are removed.
*/
public void removeAgedItems(boolean notify) {
// check if there are any values earlier than specified by the history
// count...
if (getItemCount() > 1) {
long latest = getTimePeriod(getItemCount() - 1).getSerialIndex();
boolean removed = false;
while ((latest - getTimePeriod(0).getSerialIndex())
> this.maximumItemAge) {
this.data.remove(0);
removed = true;
}
if (removed && notify) {
fireSeriesChanged();
}
}
}
/**
* Age items in the series. Ensure that the timespan from the supplied
* time to the oldest record in the series does not exceed history count.
* oldest items will be removed if required.
*
* @param latest the time to be compared against when aging data
* (specified in milliseconds).
* @param notify controls whether or not a {@link SeriesChangeEvent} is
* sent to registered listeners IF any items are removed.
*/
public void removeAgedItems(long latest, boolean notify) {
// find the serial index of the period specified by 'latest'
long index = Long.MAX_VALUE;
try {
Method m = RegularTimePeriod.class.getDeclaredMethod(
"createInstance", new Class[] {Class.class, Date.class,
TimeZone.class});
RegularTimePeriod newest = (RegularTimePeriod) m.invoke(
this.timePeriodClass, new Object[] {this.timePeriodClass,
new Date(latest), TimeZone.getDefault()});
index = newest.getSerialIndex();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
// check if there are any values earlier than specified by the history
// count...
boolean removed = false;
while (getItemCount() > 0 && (index
- getTimePeriod(0).getSerialIndex()) > this.maximumItemAge) {
this.data.remove(0);
removed = true;
}
if (removed && notify) {
fireSeriesChanged();
}
}
/**
* Removes all data items from the series and sends a
* {@link SeriesChangeEvent} to all registered listeners.
*/
public void clear() {
if (this.data.size() > 0) {
this.data.clear();
fireSeriesChanged();
}
}
/**
* Deletes the data item for the given time period and sends a
* {@link SeriesChangeEvent} to all registered listeners. If there is no
* item with the specified time period, this method does nothing.
*
* @param period the period of the item to delete (<code>null</code> not
* permitted).
*/
public void delete(RegularTimePeriod period) {
int index = getIndex(period);
if (index >= 0) {
this.data.remove(index);
fireSeriesChanged();
}
}
/**
* Deletes data from start until end index (end inclusive).
*
* @param start the index of the first period to delete.
* @param end the index of the last period to delete.
*/
public void delete(int start, int end) {
if (end < start) {
throw new IllegalArgumentException("Requires start <= end.");
}
for (int i = 0; i <= (end - start); i++) {
this.data.remove(start);
}
fireSeriesChanged();
}
/**
* Returns a clone of the time series.
* <P>
* Notes:
* <ul>
* <li>no need to clone the domain and range descriptions, since String
* object is immutable;</li>
* <li>we pass over to the more general method clone(start, end).</li>
* </ul>
*
* @return A clone of the time series.
*
* @throws CloneNotSupportedException not thrown by this class, but
* subclasses may differ.
*/
public Object clone() throws CloneNotSupportedException {
Object clone = createCopy(0, getItemCount() - 1);
return clone;
}
/**
* Creates a new timeseries by copying a subset of the data in this time
* series.
*
* @param start the index of the first time period to copy.
* @param end the index of the last time period to copy.
*
* @return A series containing a copy of this times series from start until
* end.
*
* @throws CloneNotSupportedException if there is a cloning problem.
*/
public TimeSeries createCopy(int start, int end)
throws CloneNotSupportedException {
if (start < 0) {
throw new IllegalArgumentException("Requires start >= 0.");
}
if (end < start) {
throw new IllegalArgumentException("Requires start <= end.");
}
TimeSeries copy = (TimeSeries) super.clone();
copy.data = new java.util.ArrayList();
if (this.data.size() > 0) {
for (int index = start; index <= end; index++) {
TimeSeriesDataItem item
= (TimeSeriesDataItem) this.data.get(index);
TimeSeriesDataItem clone = (TimeSeriesDataItem) item.clone();
try {
copy.add(clone);
}
catch (SeriesException e) {
e.printStackTrace();
}
}
}
return copy;
}
/**
* Creates a new timeseries by copying a subset of the data in this time
* series.
*
* @param start the first time period to copy.
* @param end the last time period to copy.
*
* @return A time series containing a copy of this time series from start
* until end.
*
* @throws CloneNotSupportedException if there is a cloning problem.
*/
public TimeSeries createCopy(RegularTimePeriod start, RegularTimePeriod end)
throws CloneNotSupportedException {
if (start == null) {
throw new IllegalArgumentException("Null 'start' argument.");
}
if (end == null) {
throw new IllegalArgumentException("Null 'end' argument.");
}
if (start.compareTo(end) > 0) {
throw new IllegalArgumentException(
"Requires start on or before end.");
}
boolean emptyRange = false;
int startIndex = getIndex(start);
if (startIndex < 0) {
startIndex = -(startIndex + 1);
if (startIndex == this.data.size()) {
emptyRange = true; // start is after last data item
}
}
int endIndex = getIndex(end);
if (endIndex < 0) { // end period is not in original series
endIndex = -(endIndex + 1); // this is first item AFTER end period
endIndex = endIndex - 1; // so this is last item BEFORE end
}
if (endIndex < 0) {
emptyRange = true;
}
if (emptyRange) {
TimeSeries copy = (TimeSeries) super.clone();
copy.data = new java.util.ArrayList();
return copy;
}
else {
return createCopy(startIndex, endIndex);
}
}
/**
* Tests the series for equality with an arbitrary object.
*
* @param object the object to test against (<code>null</code> permitted).
*
* @return A boolean.
*/
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (!(object instanceof TimeSeries) || !super.equals(object)) {
return false;
}
TimeSeries s = (TimeSeries) object;
if (!ObjectUtilities.equal(
getDomainDescription(), s.getDomainDescription()
)) {
return false;
}
if (!ObjectUtilities.equal(
getRangeDescription(), s.getRangeDescription()
)) {
return false;
}
if (!getClass().equals(s.getClass())) {
return false;
}
if (getMaximumItemAge() != s.getMaximumItemAge()) {
return false;
}
if (getMaximumItemCount() != s.getMaximumItemCount()) {
return false;
}
int count = getItemCount();
if (count != s.getItemCount()) {
return false;
}
for (int i = 0; i < count; i++) {
if (!getDataItem(i).equals(s.getDataItem(i))) {
return false;
}
}
return true;
}
/**
* Returns a hash code value for the object.
*
* @return The hashcode
*/
public int hashCode() {
int result = super.hashCode();
result = 29 * result + (this.domain != null ? this.domain.hashCode()
: 0);
result = 29 * result + (this.range != null ? this.range.hashCode() : 0);
result = 29 * result + (this.timePeriodClass != null
? this.timePeriodClass.hashCode() : 0);
// it is too slow to look at every data item, so let's just look at
// the first, middle and last items...
int count = getItemCount();
if (count > 0) {
TimeSeriesDataItem item = getDataItem(0);
result = 29 * result + item.hashCode();
}
if (count > 1) {
TimeSeriesDataItem item = getDataItem(count - 1);
result = 29 * result + item.hashCode();
}
if (count > 2) {
TimeSeriesDataItem item = getDataItem(count / 2);
result = 29 * result + item.hashCode();
}
result = 29 * result + this.maximumItemCount;
result = 29 * result + (int) this.maximumItemAge;
return result;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -