迭代有序的 HashMap 条目对的最快方法

Fastest way to iterate over ordered pairs of HashMap entries

下面的代码使用 O(N^2) 时间来处理 HashMap 的所有有序对。在此示例中,我不能使用其他数据结构,例如 TreeMap 所以想知道是否可以缩短迭代时间? Java欢迎8个成语。我想也许可以使用 months filter by condition 逻辑,其中条件可以使用 lambda 表示法表示为 months filter ( (l, r) -> (l < r) )。如果数据存储在已排序的 ArrayList 中,则此迭代将花费 O(N^2 / 2),速度快 2 倍,也是最佳时间复杂度。

Map<String, Integer> months = new HashMap<String, Integer>();
months.put("January", 1);
months.put("February", 2);
months.put("March", 3);
months.put("April", 4);
months.put("May", 5);
months.put("June", 6);
months.put("July", 7);
months.put("August", 8);
months.put("September", 9);
months.put("October", 10);
months.put("November", 11);
months.put("December", 12);
for (Map.Entry<String, Integer> entry : months.entrySet()) {
    String month = entry.getKey();
    Integer index = entry.getValue();
    for (Map.Entry<String, Integer> entry2 : months.entrySet()) {
        Integer index2 = entry2.getValue();
        if (index < index2) {
            // process ordered pair of months
            String month2 = entry2.getKey();
            System.out.println(month + " " + month2);
        }
    }
}

编辑:我找到了我的解决方案——我需要使用LinkedHashMap来保留插入月份的顺序,这样我就可以得到所有对 O(N^2 / 2) 就像我使用 ArrayList.

时间复杂度相同。具体来说,

O(N2)

O(N2 / 2)

是相同的复杂度 class。这是数学上可以证明的事实。

虽然N2大于N2/2也是对的……但这不是表征"Big O" 表示法正在解释。

要考虑的另一件事是,对列表进行排序的成本通常会超过您节省的 N^2 / 2。无论哪种方式,您都需要在整体计算中包括该成本。


我的直觉是(在较大的应用程序中)实施备选方案并测量 性能1 会更好。您正在寻求超出 "ordinary" 复杂性分析的建议,这将我们快速带入特定库方法、编译器等的行为领域。 AFAIK,没有实用的方法来获得你可以依赖的答案......除了通过经验测量。

但在你这样做之前,你应该分析你的应用程序以确保你没有浪费时间优化对没有重大影响的东西总体 表现。


1 - 特别是因为您的最新评论将多线程性能投入到一个已经过于复杂的问题中。