RecordStore 依插入順序儲存記錄,查詢特定項目效率低。RMS 提供 RecordEnumeration、RecordComparator、RecordFilter 三大介面,支援排序列舉、自訂比較與過濾查詢。
實作 compare(byte[] rec1, byte[] rec2),回傳:
PRECEDES:rec1 排在 rec2 前FOLLOWS:rec1 排在 rec2 後EQUIVALENT:相等,順序任意class ExpenseComparator implements RecordComparator {
public int compare(byte[] rec1, byte[] rec2) {
// 假設記錄前 8 bytes 為長整數時間戳記
long t1 = bytesToLong(rec1, 0);
long t2 = bytesToLong(rec2, 0);
if (t1 < t2) return PRECEDES;
else if (t1 > t2) return FOLLOWS;
else return EQUIVALENT;
}
}
效能提醒:列舉啟動時會對每筆記錄至少呼叫一次 compare,邏輯應盡量簡潔以免拖慢啟動速度。
// 取得依 ExpenseComparator 排序的列舉器
RecordEnumeration re = rs.enumerateRecords(null, new ExpenseComparator(), false);
while (re.hasNextElement()) {
byte[] rec = re.nextRecord();
// 處理記錄...
}
即使不需排序,建議改用 RecordEnumeration 取代舊式 RecordStore.getRecord(id) 迴圈,可避免刪除記錄後 ID 空洞導致的 InvalidRecordIDException。
nextRecordId() 會移動內部指標,若交替呼叫 nextRecordId() 與 nextRecord() 會導致指標錯位,拋出 InvalidRecordIDException。解法:用 RecordStore.getRecord(id) 取代 nextRecord(),並小心處理指標邊界。
實作 matches(byte[] candidate),回傳 true 保留該記錄。配合 enumerateRecords(filter, null, false) 可只列舉符合條件的記錄。
class ExpenseFilter implements RecordFilter {
public boolean matches(byte[] candidate) {
// 檢查 category 欄位是否為 MEALS
return extractCategory(candidate) == CATEGORY_MEALS;
}
}
// 使用
RecordEnumeration mealEnum = rs.enumerateRecords(new ExpenseFilter(), null, false);