Search code examples
javalistdatetimecollectionssublist

sublist in java based on date intervals


I have a class called Rating as follows:

import java.util.Date;

public class Rating implements Comparable<Rating> {

private long userId;
private long itemId;
private float ratingValue;
private Date dateTime;

public Rating(long userId, long itemId, float ratingValue, Date dateTime) {
    this.userId = userId;
    this.itemId = itemId;
    this.ratingValue = ratingValue;
    this.dateTime = dateTime;
}

@Override
public String toString() {
    return "Rating{" +
            "userId=" + userId +
            ", itemId=" + itemId +
            ", ratingValue=" + ratingValue +
            ", dateTime=" + dateTime +
            '}';
}

public Date getDateTime() {
    return dateTime;
}

public long getUserId() {
    return userId;
}

public void setUserId(long userId) {
    this.userId = userId;
}

public long getItemId() {
    return itemId;
}

public void setItemId(long itemId) {
    this.itemId = itemId;
}

public float getRatingValue() {
    return ratingValue;
}

public void setRatingValue(float ratingValue) {
    this.ratingValue = ratingValue;
}

public void setDateTime(Date datetime) {
    this.dateTime = datetime;
}

@Override
public int compareTo(Rating o) {
    return getDateTime().compareTo(o.getDateTime());
}

}

Now imagine I have a list called myList and it contains rating objects:

List<Rating> myList=New ArrayList<Object>();

Now I sort myList based on date:

Collections.sort(myList);

What I want to do is to find sublists of myList within some certain dates (for example ratings from April to May).


Solution

  • You have a few options.

    1. If you have a list, sorted or not, you can build a sublist by traversing the list and selecting the elements that are in range. The sublist would be disconnected from the original list, and the operation would have to compare every element against the selection range.
      In Java 8, the process can be simplified using streams.

    2. If you have a sorted array (not list), you can perform a binary search of the range start and end values. You can then create a list from the subrange of the array. Again, the sublist would be disconnected from the original array, but the range lookup is faster (O(log(n)) vs O(n)).

    3. If you have a sorted list, you can find the range start and end positions by traversing the list, but stop (short-circuit) when reaching the end of the range, then use subList(). The sublist is then a view, so changes in either list is reflected in the other.

    4. If you don't actually need a sorted list, you can build a TreeMap<Date, Rating>, and call subMap(). Like option 3, it provides a view of the map.

    Option 4 is likely the best if the list of rating can change.