简体   繁体   English

比较ArrayList Java中的部分对象

[英]Compare partial object in an ArrayList Java

I have an Object as follows: 我有一个Object如下:

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. 我在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. 我正在寻找任何可以实现O(1)时间的解决方案。

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. 在ArrayList中搜索现有元素将在排序的ArrayList的情况下获取O(n)(例如,您保持记录已排序),它将需要O(logn)时间。 Therefore to achieve desired functionality I'd use Map structure, indexing by title and then by date. 因此,为了实现所需的功能,我使用Map结构,按标题索引,然后按日期。 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. 使用Map Map可以防止你需要覆盖equals和hashCode方法,而我同意Map<String, Map<Date, Record>>可能看起来有点花哨或奇怪。 While will provide you with ability to update the records or check for existence within O(1) time. 虽然将为您提供更新记录或在O(1)时间内检查是否存在的能力。 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 你可以通过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插入

   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. 然后你可以将HashSet转换为你想要的List。

Make use of a Map implementation that gives you O(1) access, like HashMap or ConcurrentHashMap . 使用一个允许O(1)访问的Map实现,如HashMapConcurrentHashMap

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()));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM