我有List
个Stat
个对象,每个Stat
都有一个Date
字段。这个清单可能非常大。我想要做的是有效地将这些对象组织成日期范围(特定周)。因此,如果两个对象在同一周内出现,则它们会进入相同的List
。为简单起见,已经定义了“周”间隔,因此您不必担心会出现范围。
所以这是我目前的做法。我有一个LinkedHashMap<Date, List<Stat>>
,它按升序包含我需要的所有日期,每个条目都用空ArrayList
初始化。我正在考虑每个Stat
,遍历Map的整个entrySet,并跟踪stat也大于或等于的最接近的Date。那就像map.get(closestDate).add(stat)
。
似乎应该有更好的方法来做到这一点。也许创建像findClosestKeyGreaterThanOrEqualTo
这样的东西,这样我每次都不必遍历整个地图?
有什么想法吗?
答案 0 :(得分:2)
感谢您的回答。
我将使用NavigableMap,因为floorKey
函数正是我需要的。
答案 1 :(得分:2)
您可以使用NavigableMap
(例如TreeMap
),其中very useful methods完全用于此目的。
使用您计算的所有值和每个值的空列表初始化地图:
NavigableMap<Date, List<Stat>> map = new TreeMap<>();
// add all your weekly values associated with empty lists
然后,对于每个Stat
个对象,只需通过以下方式找到正确的列表:
final Entry<Date, List<Stat>> entry = map.floorEntry(stat.getDate());
entry.getValue().add(stat);
答案 2 :(得分:1)
这是我要做的,假设您已经可以将Date转换为weekId
:
Map<WeekId, List<Stat>>
List<Stat>
一次,并在每个周期中计算weekId
日期,然后将Stat
添加到相应的列表中,方法是从Map
中{ {1}}(如果不存在则创建一个并将其添加到地图中)您应该在循环结束时在地图中获得所需的结果。
答案 3 :(得分:1)
确保所有日期四舍五入到最接近的一周。然后使用getWeek(stat)
函数并将stat插入到地图中。一个简单的HashMultimap
即可。
您需要处理哈希码和相等的问题。假设我有数据类型
class Pair {
public int x;
public int y;
// obvious constructor
}
观察:
new Pair(1,2) == new Pair(1,2) // false
new Pair(1,2).equals(new Pair(1,2)) // false
如果你在哈希映射中使用它们作为键,它们将是不同的键。
您需要覆盖equals
和hashCode
才能克服这个问题。
Date
我们观察到:
public boolean equals(Object obj) {
return obj instanceof Date && getTime() == ((Date) obj).getTime();
}
将相应地定义Hashcode。因此,如果您关闭Date
,只有当日期同意毫秒时,您才会得到您想要的内容。
因此一个
HashMultimap<Date, Stat> map;
很好,但您应该以编程方式遵守所有日期向下舍入到最接近的一周的约定。然后做:
Date key = roundToWeek(stat);
map.insert(key, stat);
你应该做得好。