1. 程式人生 > >JAVA小程式——實現詞頻統計

JAVA小程式——實現詞頻統計

  要求  

                     i、新建文字檔案data.txt
 ii、隨便輸入一些英文單詞,單詞之間用 “空格”隔開
 iii、統計各個單詞出現的次數。
 iv、對結果進行排序
  a、安裝次數進行降序
  b、如果次數相同,安裝單詞的字典順序排序
eg:
java spring struts hibernate
spring trainning java struts
spring hibernate java bigdata
結果:
java    3
spring    3
hibernate     2
struts    2
bigdata    1

解題思路:

1,在電腦本地磁碟下建立一個名稱為data的文字檔案

                   2.通過Map集合,以鍵值對的方式去儲存單詞和出現的次數

                  3.定義一個檔案位元組讀取流,去讀取磁碟中的檔案

                  4.建立一個BufferReader的緩衝流,將字元流物件傳進去,提高讀取的效率

                5.建立一個spilt陣列,用來分割字串,通過呼叫map的key值獲取value,進行單詞統計。

               6.利用TreeMap實現Comparator介面,對Map集合進行排序

  補充

BufferReader沒有緩衝區時,每次讀取操作都會導致一次檔案讀取操作(就是告訴作業系統核心我要讀這個檔案的這個部分,麻煩你幫我把它取過來)。


有緩衝區時,會一次性讀取很多資料,然後按要求分次交給上層呼叫者。
讀取塊大小通常是按最適合硬體的大小來讀的,因為對於硬體來說,一次讀取一塊連續資料(比如 1K)和一次讀取一個位元組需要的時間幾乎是一樣的(都是一次讀操作,只是最終提交的資料量有差異)。帶緩衝的 I/O 和不帶緩衝的相比效率差異是非常顯著的,你可以自行寫程式測試。

說到java reader快取, 其實有兩層快取:
        OS快取, 把磁碟資料 讀入記憶體, 通過read ahead, io scheduler等減少磁碟讀取次數.
        App快取, 做快取/預讀, 即BufferredReader的角色.

        BufferredReader的作用, 我的理解, 一) 減少System Call次數; 二) 減少磁碟讀取次數.

map集合的遍歷:


比較器:


具體程式碼實現:      

data.txt內容:

  java spring struts hibernate
spring trainning java struts
spring hibernate java bigdata

JAVA程式碼:             

import java.io.*;
import java.util.*;

public class WordFrequencyCount {
    public static void main(String[] args) {
        String string = "";
        //通過鍵值對的方式去分別儲存字串和出現的次數
Map<String,Integer>map = new HashMap<String, Integer>();
        try {
            //定義一個檔案位元組讀取流,去讀取磁碟中的檔案
FileInputStream fis = new FileInputStream("D:\\18-03班\\面向物件\\IO流\\data.txt");
            //建立一個BufferedReader的緩衝流,將字元流物件放入進去,提高讀取的效率
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
            String temp = "";
            try {
                //從BufferReader中讀取下一行
while ((temp = br.readLine()) != null){
                    string = string + temp;//讀取到的檔案資訊
}
            } catch (IOException e) {
                e.printStackTrace();
            }
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }
        //建立一個spilt陣列,分割字串,來統計單詞出現的次數
String [] spilt = string.split(" ");
        for (int i = 0;i<spilt.length;i++){

           //map.get(),通過鍵名來獲取鍵值
            if (map.get(spilt[i]) == null){
//map.put()將鍵值儲存在map集合中,如果存在,那麼就覆蓋該鍵值,如果不存在就新建一個。
                map.put(spilt[i],1);
            }else {
                int frequency = map.get(spilt[i]);
                map.put(spilt[i],++frequency);
            }
        }
//利用TreeMap實現Comparator介面

Comparator<Map.Entry<String, Integer>> valueComparator = new Comparator<Map.Entry<String,Integer>>() {

  public int compare(Map.Entry<String, Integer> o1,Map.Entry<String, Integer> o2) { 

                 /*return o1.getValue()-o2.getValue();//升序排序*/

                    return o2.getValue()-o1.getValue();//降序排序} };

 // map轉換成list進行排序,Entry是Map中的一個靜態內部類,用來表示Map中的每個鍵值對,
 //除非使用了靜態匯入import static java.util.Map.*,否則Map不可以省略。
 // map.EntrySet(),實現了Set介面,裡面存放的是鍵值對.

List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String,Integer>>(map.entrySet()); 

  // 排序

Collections.sort(list,valueComparator); 

  // 預設情況下,TreeMap對key進行升序排序

System.out.println("------------map按照value降序排序--------------------");

  for (Map.Entry<String, Integer> entry : list) { 

 System.out.println(entry.getKey() + ":" + entry.getValue());

             }

   }
}
執行結果: