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

时间:2016-07-29 17:04:47

标签: java list datetime collections sublist

我有一个名为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的子列表(例如4月到5月的评分)。

4 个答案:

答案 0 :(得分:1)

我认为您应该使用Unix time format来存储时间戳。您可以使用Date类中的getime()函数进行转换。如果按升序对unix时间戳排序,则首先获得最早的日期。希望这会有所帮助。

答案 1 :(得分:1)

如果您使用的是Java 8(并且您应该使用Java 8:&gt;),请使用流式语法:

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

我假设您知道如何构建earlierDatelaterDate

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

您有几个选择。

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

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

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

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

  5. 如果评级列表可以改变,选项4可能是最好的。