I have an Object as follows:
public class Record{
Int ID;
String title;
Date date;
Duration time;
public Record createRecord(int ID, String title, Date date, Duration time){
this.ID= ID;
this.title = title;
this.date = date;
this.time = time;
return this;
}
}
I am storing multiple objects in a List. While inserting a new record, I need to check if the list already has an object with ONLY the same title and date, and replace the time in it.
I am looking for any solution which can achieve O(1) time.
Searching in ArrayList for existing element will take you O(n) in case of sorted ArrayList (eg you maintain records sorted) it will require O(logn) time. Therefore to achieve desired functionality I'd use Map structure, indexing by title and then by date. Something like this:
// Create general records DB
Map<String, Map<Date, Record>> records = new HashMap<>();
// Create sub DB for records with same ID
Map<Date, Record> subRecords = new HashMap<>();
// Assuming you've got from somewhere id, title and rest of the parameters
subRecords.put(recordDate, new Record(id, title, time, duration));
records.put(recordId, subRecords)
// Now checking and updating records as simple as
sub = records.get(someTitle); // Assuming you've got someTitle
if (sub != null) {
record = sub.get(someDate); // Same for someDate
if (record != null) {
record.updateTime(newTime);
}
}
Using Map of Map will prevent from you the need to override equals and hashCode methods, while I'd agree that Map<String, Map<Date, Record>>
might look a bit fancy or weird. While will provide you with ability to update the records or check for existence within O(1) time. Additional nit is that you do not need to create a record to check for existence or for update, you can directly use Title and Date to retrieve what you needed.
You could do that by a HashSet
and implement the
@Override
public boolean equals(Object obj) {
if(this == obj) return true;
if(!(obj instanceof Record)) return false;
Record otherRecord = (Record)obj;
return (this.time.equals(otherRecord.time) && this.title.equals(otherRecord.title));
}
@Override
public int hashCode() {
int result = titile != null ? titile.hashCode() : 0;
result = 31 * result + (time != null ? time.hashCode() : 0);
return result;
}
And use a hashset to insert
HashSet hset = new HashSet<Record>();
if(!hset.add(record)){
hset.remove(record);
hset.add(record);
}
Then you could convert the HashSet to the List you want.
Make use of a Map implementation that gives you O(1)
access, like HashMap
or ConcurrentHashMap
.
Psuedo-code:
class Record {
static class Key {
Date date
String title
// proper hashCode and equals
}
Date date
String title
int id
Time time
Key getKey() {...}
}
Map<Record.Key, Record> recordMap = new HashMap<>();
for (record : records) {
recordMap.merge(record.getKey(), record,
(oldRecord, newRecord) -> oldRecord.setTime(newRecord.getTime()));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.