簡單錯誤記錄——HashMap和LinkedHashMap

最近在刷題的過程中,在使用HashMap進行文件排序遇到的小問題。

題目:

開發一個簡單錯誤記錄功能小模塊,能夠記錄出錯的代碼所在的文件名稱和行號。 
處理:
1.記錄最多8條錯誤記錄,對相同的錯誤記錄(即文件名稱和行號完全匹配)只記錄一條,錯誤計數增加;(文件所在的目錄不同,文件名和行號相同也要合併)
2.超過16個字符的文件名稱,只記錄文件的最後有效16個字符;(如果文件名不同,而只是文件名的後16個字符和行號相同,也不要合併)
3.輸入的文件可能帶路徑,記錄文件名稱不能帶路徑

輸入描述:
一行或多行字符串。每行包括帶路徑文件名稱,行號,以空格隔開。

    文件路徑爲windows格式

    如:E:\V1R2\product\fpgadrive.c 1325


輸出描述:
將所有的記錄統計並將結果輸出,格式:文件名代碼行數數目,一個空格隔開,如: fpgadrive.c 1325 1 

    結果根據數目從多到少排序,數目相同的情況下,按照輸入第一次出現順序排序。

    如果超過8條記錄,則只輸出前8條記錄.

    如果文件名的長度超過16個字符,則只輸出後16個字符

輸入例子1:
E:\V1R2\product\fpgadrive.c 1325

輸出例子1:
fpgadrive.c 1325 1

自己的代碼:

在使用HashMap的時候,提交不通過,而使用LinkedHashMap的時候卻提交通過。

public static  void main(String []args) {
        Scanner sr = new Scanner(System.in);
        HashMap<String, Integer> map = new HashMap<>();  //LinkedHashMap
        do {

            String str = sr.next();
            int index = sr.nextInt();
            int in  = str.lastIndexOf('\\');
            str = str.substring(in+1, str.length()) + " " + index;
            if (map.containsKey(str)) {
                map.put(str, map.get(str) + 1);
            } else {
                map.put(str, 1);
            }

        } while (sr.hasNext());
        sr.close();
        //對記錄排序
        //對記錄進行排序
        List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            //降序
            @Override
            public int compare(Entry<String, Integer> arg0, Entry<String, Integer> arg1) {
                return (arg1.getValue() - arg0.getValue()) == 0 ? (arg0.getValue() - arg1.getValue()) : (arg1.getValue() - arg0.getValue());
            }
        });
        //只輸出前8條
        int m = 0;
        for (Map.Entry<String, Integer> mapping : list) {
            m++;
            if (m <= 8) {
                String[] str = mapping.getKey().split(" ");
                String k = str[0].length() > 16 ? str[0].substring(str[0].length() - 16) : str[0];
                String n = str[1];
                System.out.println(k + " " + n + " " + mapping.getValue());
            } else {
                break;
            }
        }
    }

HashMap輸出結果:

這裏寫圖片描述

總結分析:LinkedHashmap 的特點是put進去的對象位置未發生變化,而HashMap會發生變化.

java爲數據結構中的映射定義了一個接口java.util.Map;它有四個實現類,分別是HashMap Hashtable LinkedHashMap 和TreeMap.

Map主要用於存儲健值對,根據鍵得到值,因此不允許鍵重複(重複了覆蓋了),但允許值重複。
Hashmap 是一個最常用的Map,它根據鍵的HashCode值存儲數據(重複存儲入相同的hashCode不會導致錯誤發生,但只會保留一個值,equlas和hashCode的規則,hashCode不同的可能equals。但是不equals一定hashCode不同),根據鍵可以直接獲取它的值,具有很快的訪問速度,遍歷時,取得數據的順序是完全隨機的

HashMap最多隻允許一條記錄的鍵爲Null;允許多條記錄的值爲 Null;

HashMap默認按照key的升序排列存儲的數據,因此會在一定程度上影響到性能。

HashMap不支持線程的同步,即任一時刻可以有多個線程同時寫HashMap;可能會導致數據的不一致。

如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap;但是這樣的話性能會有影響。

Hashtable與 HashMap類似,它繼承自Dictionary類,不同的是:它不允許記錄的鍵或者值爲空;它支持線程的同步,即任一時刻只有一個線程能寫Hashtable,因此也導致了 Hashtable在寫入時會比較慢。

LinkedHashMap 是HashMap的一個子類,保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的(先進先出,類似棧).也可以在構造時用帶參數,按照應用次數排序在遍歷的時候會比HashMap慢(因爲linkedhashmap需要保存插入的順序屬於需要額外開銷),不過有種情況例外,當HashMap容量很大,實際數據較少時,遍歷起來可能會比LinkedHashMap慢,因爲LinkedHashMap的遍歷速度只和實際數據有關,和容量無關,而HashMap的遍歷速度和他的容量有關。

TreeMap實現SortMap接口,能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也可以指定排序的比較器,當用Iterator 遍歷TreeMap時,得到的記錄是排過序的。

一般情況下,我們用的最多的是HashMap,在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。但如果您要按自然順序或自定義順序遍歷鍵,那麼TreeMap會更好。如果需要輸出的順序和輸入的相同,那麼用LinkedHashMap可以實現,它還可以按讀取順序來排列.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章