按日期排序HashMap

时间:2015-09-08 17:44:12

标签: java sorting hashmap xpages

在Java类中,我有一个按日期重新编译现有HashMap的方法。 HashMap的类型为<String, Object>,其中Object包含一个名为expPayDate的字段,而键字符串是一个变为字符串的序列号。所以我需要遍历sourceMap中的项目并找到包含该项目的项目。最新的日期然后以正确的顺序将其复制到tempMap。我的问题是确定具有最新日期的项目的最佳方法。

6 个答案:

答案 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)

  1. 通过调用地图的entrySet()方法

  2. 获取所有条目
  3. 创建自定义Comparator以根据值

  4. 对条目进行排序
  5. Entry设置转换为List

  6. 通过传递值比较器使用Collections.sort()方法对条目列表进行排序

  7. 通过按排序顺序添加条目来创建LinkedHashMap

  8. 查看示例代码@ 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(在日期充当堆))将是完全合理的,具体取决于您对此数据结构的访问模式。