既然说到词频,那肯定是要用键值对来保存单词和对应的次数了。
这里插入一下HashMap和TreeMap:
HashMap:基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()[可以重写hashCode()和equals()],为了优化HashMap空间的使用,您可以调优初始容量和负载因子。适用于在Map中插入、删除和定位元素。
(1)HashMap(): 构建一个空的哈希映像
(2)HashMap(Map m): 构建一个哈希映像,并且添加映像m的所有映射
(3)HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像
(4)HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像
TreeMap:基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。适用于按自然顺序或自定义顺序遍历键(key)。
(1)TreeMap():构建一个空的映像树
(2)TreeMap(Map m): 构建一个映像树,并且添加映像m中所有元素
(3)TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序
(4)TreeMap(SortedMap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序
HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。
为了让单词自动按字母顺序排列(看着顺眼),我用了TreeMap,但是TM自定义Comparator只可以对key设置,不能设置value的排序规则,因为它是靠key搭建的树,所以用到的方法是:先转成集合List,里面放了TM的Entry键值对,对这个集合的排序写一个Comparator方法。
1 importjava.io.BufferedReader;2 importjava.io.File;3 importjava.io.FileReader;4 importjava.io.IOException;5 importjava.util.ArrayList;6 importjava.util.Collections;7 importjava.util.Comparator;8 importjava.util.List;9 importjava.util.Map;10 importjava.util.TreeMap;11
12 public classtexMain {13 public static void main(String[] args) throwsIOException {14 File file=new File("E:/test.txt");15 BufferedReader bReader= new BufferedReader(newFileReader(file));16
17 TreeMap map=new TreeMap();18 String line=null;19 while((line=bReader.readLine())!=null) {20 String[] strs=line.trim().split("[^A-Za-z]");21 for(String s:strs) {22 if(s.trim().length()==0)continue;23 if(!map.containsKey(s))24 map.put(s,1);25 else{26 map.put(s, map.get(s)+1);27 }28 }29 }30 bReader.close();31 List> list=new ArrayList<>(map.entrySet());32 Collections.sort(list,new Comparator>(){33 @Override34 public int compare(java.util.Map.Entry o1, java.util.Map.Entryo2) {35
36 returno2.getValue().compareTo(o1.getValue());37 }38 });39 for(Map.Entrym:list) {40 System.out.println(m.getKey()+" "+m.getValue());41 }42 System.out.println(list.get(0).getKey()+" "+list.get(0).getValue());43 }44 }
PS:HashMap的负载因子:当负载因子较大时,去给table数组扩容的可能性就会少,所以相对占用内存较少(空间上较少),但是每条entry链上的元素会相对较多,查询的时间也会增长(时间上较多)。反之就是,负载因子较少的时候,给table数组扩容的可能性就高,那么内存空间占用就多,但是entry链上的元素就会相对较少,查出的时间也会减少。所以才有了负载因子是时间和空间上的一种折中的说法。所以设置负载因子的时候要考虑自己追求的是时间还是空间上的少。