既然说到词频,那肯定是要用键值对来保存单词和对应的次数了。
这里插入一下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 import java.io.BufferedReader; 2 import java.io.File; 3 import java.io.FileReader; 4 import java.io.IOException; 5 import java.util.ArrayList; 6 import java.util.Collections; 7 import java.util.Comparator; 8 import java.util.List; 9 import java.util.Map; 10 import java.util.TreeMap; 11 12 public class texMain { 13 public static void main(String[] args) throws IOException { 14 File file=new File("E:/test.txt"); 15 BufferedReader bReader= new BufferedReader(new FileReader(file)); 16 17 TreeMap<String, Integer> map=new TreeMap<String, Integer>(); 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<Map.Entry<String,Integer>> list=new ArrayList<>(map.entrySet()); 32 Collections.sort(list,new Comparator<Map.Entry<String, Integer>>(){ 33 @Override 34 public int compare(java.util.Map.Entry<String, Integer> o1, java.util.Map.Entry<String, Integer> o2) { 35 36 return o2.getValue().compareTo(o1.getValue()); 37 } 38 }); 39 for(Map.Entry<String, Integer> m: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链上的元素就会相对较少,查出的时间也会减少。所以才有了负载因子是时间和空间上的一种折中的说法。所以设置负载因子的时候要考虑自己追求的是时间还是空间上的少。