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());

             }

   }
}
运行结果:

                

猜你喜欢

转载自blog.csdn.net/weixin_42047611/article/details/80592285