在Java类中,我有一个按日期重新编译现有HashMap的方法。 HashMap的类型为<String, Object>
,其中Object包含一个名为expPayDate的字段,而键字符串是一个变为字符串的序列号。所以我需要遍历sourceMap中的项目并找到包含该项目的项目。最新的日期然后以正确的顺序将其复制到tempMap。我的问题是确定具有最新日期的项目的最佳方法。
答案 0 :(得分:12)
您最好的选择是SortedMap使用Comparator界面。
以下是一个例子:
public SortedMap<String, Object> getSortedMap(Map<String, Object> originalMap) {
SortedMap<String, Object> tmpMap = new TreeMap<String, Object>(new Comparator<String>(){
@Override
public int compare(String key1, String key2) {
//logic for comparing dates
}
});
tmpMap.putAll(originalMap);
return tmpMap;
}
答案 1 :(得分:4)
通过调用地图的entrySet()
方法
创建自定义Comparator
以根据值
将Entry
设置转换为List
通过传递值比较器使用Collections.sort()
方法对条目列表进行排序
通过按排序顺序添加条目来创建LinkedHashMap
。
查看示例代码@ Sort HasMap by value
答案 2 :(得分:4)
为简单起见,我假设您的地图类型更像Map<String, MyClass> map
,其中MyClass
的方法类似getDate()
,返回expPayDate
。
我的问题是确定具有最新日期的项目的最佳方法。
如果你想找到值包含最大日期的单个地图条目,你不需要对整个地图进行排序最多会给你O(n * LOGN)。你需要的是对map中所有元素的简单迭代,并将它们与当前max进行比较,这将是O(n)操作。
您可以使用stream()
(Java 8中添加的功能)及其max
方法。此方法需要Comparator
,您可以使用comparing
方法轻松创建一个并传递lambda表达式,该表达式将返回比较时应使用的值。
所以你的代码看起来像
//import java.util.Map.Entry;
Optional<Entry<String, MyClass>> max = map.entrySet().stream()
.max(Comparator.comparing(e -> e.getValue().getDate()));
Entry<String, MyClass> entry = max.get();
MyClass maxMC = entry.getValue();
如果你不能使用Java 8,你可以编写自己的方法,迭代元素并找到最大值。这种方法看起来像
public static <T> T max(Iterable<T> iterable, Comparator<T> comp) {
Iterator<T> it = iterable.iterator();
T max = null;
if (it.hasNext()) {
max = it.next();
}
while (it.hasNext()) {
T tmp = it.next();
if (comp.compare(max, tmp) < 0)
max = tmp;
}
return max;
}
你可以像
一样使用它Comparator<Entry<String, MyClass>> myComparator = new Comparator<Entry<String, MyClass>>() {
@Override
public int compare(Entry<String, MyClass> o1, Entry<String, MyClass> o2) {
return o1.getValue().getDate().compareTo(o2.getValue().getDate());
}
};
Entry<String, MyClass> maxEntry = max(map.entrySet(), myComparator);
MyClass max = maxEntry.getValue();
答案 3 :(得分:4)
使用TreeMap而不是HashMap。它将在插入时自动排序。
Map< Date, Object> m = new TreeMap< Date, Object>();
或者,如果您有一个现有的HashMap并想要基于它创建一个TreeMap,请将其传递给构造函数:
Map< Date, Object> sortedMap = new TreeMap< Date, Object>(m);
希望它会对你有所帮助。
答案 4 :(得分:3)
如果您只需要最小或最大日期,则每个循环的简单操作就足够了:
Date maxDate = null;
for (Entry<String, Object> item: hashMap.entrySet())
if (maxDate == null || maxDate before((Date)item.getValue()))
maxDate = (Date)item.getValue();
这种方式复杂度仅为O(n),插入和删除操作比使用sortedMap
便宜。无论如何,我认为 patstuart 的建议(使用sortedMap
)更优雅。
答案 5 :(得分:1)
正确的解决方案取决于您的性能限制。
如果您的问题只是找到具有最新日期的项目,那么如果O(n)性能正常,您可以在HashMap中扫描values()并找到最小值。
这取决于您相对于数据结构上的其他访问需要执行此操作的频率。使用SortedMap或使用辅助数据结构(例如PriorityQueue(在日期充当堆))将是完全合理的,具体取决于您对此数据结构的访问模式。