简单错误记录——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可以实现,它还可以按读取顺序来排列.

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页