java 中的子列表基于日期间隔

sublist in java based on date intervals

我有一个 class 叫做 Rating 如下:

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

}

现在假设我有一个名为 myList 的列表,它包含评级对象:

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

现在我根据日期对 myList 进行排序:

Collections.sort(myList);

我想做的是在某些特定日期(例如四月到五月的评级)中找到 myList 的子列表。

我认为您应该使用日期 class 中的 Unix time format to store time-stamp. You can use getime() 函数进行转换。如果您按升序对 unix 时间戳进行排序,则会首先获得最旧的日期。希望这会有所帮助。

如果您使用 Java 8(您应该使用 Java 8 :>),请使用流式语法:

result = myList.stream().filter(x -> x.getDateTime() != null && x.getDateTime().compareTo(earlierDate) >= 0 && x.getDateTime().compareTo(laterDate) <= 0).collect(Collectors.toList());

我假设您知道如何构造 earlierDatelaterDate

您可以尝试这样检查范围并将其添加到子列表中:

//Range values for date
    Date startDate=new Date("06/01/2007");
    Date endDate=new Date("07/01/2007");
    ArrayList<Rating> sublist=new ArrayList<Rating>();
    //check if list date comes in the range , If true add to sublist else not
    boolean result=false;
    for(int i=0;i<myList.size();i++)
    {
        result=!(myList.get(i).getDateTime().before(startDate) || myList.get(i).getDateTime().after(endDate));
        if(result)
            sublist.add(myList.get(i));

    }
    for(int i=0;i<sublist.size();i++)
    {
        System.out.println(sublist.get(i).toString());
    }

您有几个选择。

  1. 如果您有一个列表,无论是否排序,您都可以通过遍历列表并选择范围内的元素来构建子列表。子列表将与原始列表断开连接,操作必须将每个元素与选择范围进行比较。
    在Java8中,可以使用流来简化流程。

  2. 如果您有一个排序数组(不是列表),您可以对范围的起始值和结束值执行二进制搜索。然后,您可以从数组的子范围创建一个列表。同样,子列表将与原始数组断开连接,但范围查找速度更快(O(log(n)) vs O(n))。

  3. 如果你有一个排序列表,你可以通过遍历列表找到范围的开始和结束位置,但是当到达范围的末尾时停止(短路),然后使用subList()。子列表然后是 视图,因此任一列表中的更改都会反映在另一个列表中。

  4. 如果您实际上不需要排序列表,您可以构建一个TreeMap<Date, Rating>,然后调用subMap()。与选项 3 一样,它提供地图的 视图

如果评级列表可以更改,选项 4 可能是最佳选择。