A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 廉伟 中级黑马   /  2012-8-29 13:09  /  1594 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 廉伟 于 2012-8-29 13:11 编辑
  1. package javase2.day03;

  2. import java.io.BufferedInputStream;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.Collections;
  9. import java.util.Comparator;
  10. import java.util.HashMap;
  11. import java.util.HashSet;
  12. import java.util.Iterator;
  13. import java.util.List;
  14. import java.util.Map;
  15. import java.util.Map.Entry;
  16. import java.util.Set;

  17. public class CharCounterDemo {
  18.   public static void main(String[] args)
  19.     throws IOException {
  20.     String file = "src/javase2/day03/book.txt";
  21.     Map<Character, Integer> map = countAll(file, "GBK");
  22.     //System.out.println(map);
  23.     int all = 0;//字符数量
  24.     Collection<Integer> values = map.values();
  25. //    for(Iterator<Integer> i=values.iterator(); i.hasNext();){
  26. //      int n = i.next();
  27. //      all+=n;
  28. //    }
  29.     for(int n:values){
  30.       all+=n;
  31.     }
  32.     //排序输出:
  33.     List<Entry<Character, Integer>> list =
  34.       new ArrayList<Map.Entry<Character,Integer>>(
  35.           map.entrySet());
  36.     Collections.sort(list,
  37.       new Comparator<Entry<Character, Integer>>() {
  38.       public int compare(Entry<Character, Integer> o1,
  39.           Entry<Character, Integer> o2) {
  40.         return -(o1.getValue() - o2.getValue());
  41.       }
  42.     });
  43.     for(int i=0;i<10; i++){
  44.       Entry<Character, Integer> entry = list.get(i);
  45.       char ch = entry.getKey();
  46.       int n = entry.getValue();
  47.       System.out.println(ch + ":"+n+" "+((double)n/all)*100);
  48.     }
  49.     System.out.println("不重复字符数量:"+map.size());  
  50.     System.out.println("共计字符:"+all);
  51.    
  52.   }
  53.   public static Map<Character, Integer>
  54.     countAll(String file, String encoding)
  55.       throws IOException{
  56.     InputStreamReader in = new InputStreamReader(
  57.         new BufferedInputStream(
  58.             new FileInputStream(file)), encoding);
  59.     Set<Character> chs = new HashSet<Character>();
  60.     chs.add('\n');
  61.     chs.add('\r');
  62.     chs.add(' ');
  63.     chs.add(',');
  64.     chs.add(',');
  65.     chs.add('。');
  66.     chs.add(' ');
  67.     Map<Character, Integer> map =
  68.       new HashMap<Character, Integer>();
  69.     int ch;
  70.     while((ch=in.read())!=-1){
  71.       char c = (char)ch;
  72.       if(chs.contains(c)){//忽略掉 回车等字符
  73.         continue;
  74.       }
  75.       Integer n = map.get(c);
  76.       map.put(c, n==null ? 1 : n+1);
  77.     }
  78.     in.close();
  79.     return map;
  80.   }
  81. }
复制代码
Map<Character, Integer> map = countAll(file, "GBK");是什么意思??怎么理解??
Collection<Integer> values = map.values();是什么意思??怎么理解??
List<Entry<Character, Integer>> list =
      new ArrayList<Map.Entry<Character,Integer>>(
          map.entrySet());是什么意思??怎么理解??就是这句,我什么都不懂!
为什么要定义这个呢: Set<Character> chs = new HashSet<Character>();是什么意思??怎么理解??

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1

查看全部评分

4 个回复

正序浏览
本帖最后由 陈莹 于 2012-8-29 20:05 编辑

你可以先把泛型去掉,那样有助于你分析,理解之后再加上泛型:

Map map = countAll(file, "GBK");你调用countAll函数返回一个Map集
加上泛型:
Map<Character, Integer> map = countAll(file, "GBK");说明该Map集合中存放的键是Character类型的,值是Integer的。

Collection values = map.values();定义一个Collection集合,存放Map集合中的值,也就是相应字符出现的次数。
加上泛型:
Collection<Integer> values = map.values();泛型说明Collection集合中存放的是Integer类型的,你上面定义的Map集合中值是Integer类型的,现在取出Map集合中的值存放到Collection中,所以对应的类型也是Integer类型的。

List<Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character,Integer>>( map.entrySet());
这句话你的一层一层分析,首先,拿出最外层的东西
List list = new ArrayList(map.entrySet());
map.entrySet返回一个包含map集合中键值关系的set集合,
这句话定义一个List集合,该集合存放的是就是该set集合,也就是字符和它出现的次数。
然后给List集合加上泛型, 为Map.Entry类型(键值对)的,Map.Entry中又有泛型,要求键为Character类型,值为Integer类型。
Entry是一个HashMap类的内部静态类。实现了Map.Entry接口,这里用Map.Entry就行了,没必要用Entry。

Set<Character> chs = new HashSet<Character>();定义一个HashSet集合,存放数据类型Character。这个集合中存放你要忽略计数的字符,像换行,空格等。在遍历字符时要判断该字符是否被这个集合包含,也是说是不是这个集合中有的,假如有,就忽略不计。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
授之与鱼 再授之与渔 下面的总结 能更好的帮你理解你所提出的问题

Map集合:
        特点:
        它是集合框架中的顶层。
        它一次存储一对元素,一个叫键,一个叫值,也就是键值对。
        Collection一次存一个,称为单列集合。
        Map一次存一对,称为双列集合。
        map集合中必须保证键的唯一性。
        如果存储键值对时,键出现重复,新值覆盖旧值,其实map集合存储的是映射关系。
Map常见的方法:
        该集合存储的键值对,一对一对的往里存,而且要保证键的唯一性。
        1、添加:
                put(key,value);
                putAll()
        2、删除:
                clear();
                remove(key);根据键来删,因为键唯一。
        3、判断:
                containKey():
                containVlaue();
                isEmpty();
        4、获取:
                get(Object key);
                size();获取长度。
                values();获取所有的值。张三对的北京人,李四对应上海人。所以要把所有的值都获取,看。
                entrySet();将map集合中的映射关系
                map.Entry其实Entry也是一个接口,它是map接口中的一个内部接口。
                Interface Map{
                        public static interface Entry{
                                public abstract Object getKey();
                                public abstract Object getValue();
                               
                        }
                }       
                keySet();将map中所有的键都存入了set集合,因为set具备迭代器,所以可以迭代方式取出所有的键,在根据get方法获取每一个键对应的值。
                Map集合的取出原理:将map集合转成set集合,在通过迭代器取出
                以上两个知识点:有什么特点?什么时候用?怎么用?晚上回家查资料?预习
2、Map
        |--Hashtable:低层是哈希表数据结构,不可以存入null作为键和null作为值。该集合是线程同步的。JDK1.0
        |--HashMap:低层是哈希表数据结构,该集合是不同步的,允许使用null键和null值。JDK1.2效率高
        |--TreeMap:低层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序。
       
        和set很像,其实set低层就是使用了Map集合。
       
3、扩展知识:
        map集合被使用是因为具备映射关系。
       
4、collections:
        面试题:collections和collection有什么区别?
        1、里面的方法都是静态的。
        2、没有构造函数是因为不用创建对象的。
        特点:
        1、sort()可以对集合类进行排序。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
Map<Character, Integer> map = countAll(file, "GBK");是什么意思??怎么理解??  新建一个map集合  并且定义为“gbk”编码表编码
Collection<Integer> values = map.values();是什么意思??怎么理解??       把双列集合的map的值 赋给 单列集合values
List<Entry<Character, Integer>> list =
      new ArrayList<Map.Entry<Character,Integer>>(
          map.entrySet());是什么意思??怎么理解??就是这句,我什么都不懂!       map调用取出键值对并且存入集合的方法
为什么要定义这个呢: Set<Character> chs = new HashSet<Character>();是什么意思??怎么理解??  新建一个set集合
回复 使用道具 举报
Map<Character, Integer> map = countAll(file, "GBK");是什么意思??怎么理解??//定义一个Map集合,把文件存进去,指定码表为GBK
Collection<Integer> values = map.values();是什么意思??怎么理解??//把map里的值赋给collection
List<Entry<Character, Integer>> list =   new ArrayList<Map.Entry<Character,Integer>>(
          map.entrySet());是什么意思??怎么理解??就是这句,我什么都不懂!//entryset是取出map里的键值对存成一个set集合
为什么要定义这个呢: Set<Character> chs = new HashSet<Character>();是什么意思??怎么理解??、//就是创建一个存字符的set集合

楼主应该还没看到集合吧,看到就能懂了

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马