简体   繁体   English

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

[英]sublist in java based on date intervals

I have a class called Rating as follows: 我有一个叫做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());
}

} }

Now imagine I have a list called myList and it contains rating objects: 现在,假设我有一个名为myList的列表,它包含评分对象:

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

Now I sort myList based on date: 现在我根据日期对myList进行排序:

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). 我想做的是在某些日期内找到myList的子列表(例如,从4月到5月的评分)。

I think you should use Unix time format to store time-stamp. 我认为您应该使用Unix时间格式来存储时间戳。 You can use getime() function from Date class for conversion. 您可以使用Date类中的getime()函数进行转换。 If you sort on unix timestamp in ascending order you get the oldest date first. 如果您按升序对Unix时间戳进行排序,则会首先获取最早的日期。 Hope this will help. 希望这会有所帮助。

If you're on Java 8 (and you should be on Java 8 :>), use the streaming syntax: 如果您使用的是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());

I assume you know how to construct earlierDate and laterDate . 我假设您知道如何构造earlierDatelaterDate

You can try checking the range like this and adding it into sublist: 您可以尝试检查以下范围,并将其添加到子列表中:

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

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. 在Java 8中,可以使用流简化该过程。

  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) ). 同样,子列表将与原始数组断开连接,但是范围查找更快( 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() . 如果您有一个排序列表,则可以通过遍历列表来找到范围的开始和结束位置,但是在到达范围的末尾时可以停止(短路),然后使用subList() The sublist is then a view , so changes in either list is reflected in the other. 子列表是一个view ,因此任一列表中的更改都会反映在另一个列表中。

  4. If you don't actually need a sorted list, you can build a TreeMap<Date, Rating> , and call subMap() . 如果您实际上不需要排序列表,则可以构建TreeMap<Date, Rating> ,然后调用subMap() Like option 3, it provides a view of the map. 像选项3一样,它提供了地图视图

Option 4 is likely the best if the list of rating can change. 如果评级列表可以更改,则选项4可能是最好的。

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

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