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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张海涛 中级黑马   /  2013-1-15 01:30  /  2155 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张海涛 于 2013-1-15 17:30 编辑

import java.util.*; class Mycom implements Comparator<Character>{ public int compare (Character s1,Character s2) { int a=s1.compareTo(s2); // return a; if (a==0) return 0; else return 1; } } public class TreeMapTest { public static void main(String args[]) { String s ="abca"; String str = letterCount(s); System.out.println(str); } public static String letterCount(String s) { int cou = 0; char[] ch = s.toCharArray(); TreeMap<Character,Integer>tm = new TreeMap<Character,Integer>(new Mycom()); for(int i=0;i<ch.length;i++) { Integer value = tm.get(ch ); if(value != null) cou = value; cou++; tm.put(ch ,cou); cou = 0; } //返回此映射中包含的键的 Set 视图。 Set<Character>keyset = tm.keySet(); Iterator<Character>it1 = keyset.iterator(); while(it1.hasNext()) { Character c = it1.next(); Integer count = tm.get(c);//get()返回指定键所映射的值; //如果此映射不包含该键的映射关系,则返回 null。 System.out.print(c+"("+count+")"); } System.out.println(); System.out.println("==========================================="); //返回此映射中包含的映射关系的 Set 视图。 Set<Map.Entry<Character,Integer>>entryset = tm.entrySet();//返回此映射中包含的映射关系的 Set 视图 Iterator<Map.Entry<Character,Integer>>it = entryset.iterator(); StringBuilder sb = new StringBuilder(); while(it.hasNext()) { Map.Entry<Character,Integer>me = it.next(); char c = me.getKey(); int x = me.getValue(); sb.append(c+"("+x+")"); } return sb.toString(); } } 程序运行的结果为 {a=1;b=1,c=1,a=2},不是说put方法向TreeMap中添加映射关系时,如果该映射以前包含此键的映射关系,那么将替换旧值,但是这里为什么出现两个相同的键a呢? 假如用绿色代码替代红色代码,那么运行结果就是对的,{a=2;b=1,c=1},这是为什么呢?

点评

标注下红色和绿色部分  发表于 2013-1-15 09:54

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
其主要原因就是你覆写了 TreeMap的 Compare()方法。
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>(new Mycom()); 这段代码
换成TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
就可以得到你想要的结果

而且你应该对比看一下你的Compare()方法是不是写的正确
回复 使用道具 举报
仔细看了下你的代码,以上代码是存在有问题的,将代码Integer value = tm.get(ch ); tm.put(ch ,cou);中ch分别换成ch[]可以得到你所说的现象。
经过编译运行观察,你所说的绿色代码应该是指比较器里compare方法中的  :绿色return a;  红色:if (a==0){ return 0;}else{return 1;}
出现你所说的问题的原因是你复写compare的时候,采用红色代码部分时,将原来比较值为负的部分变成了正。
而真正的比较过程是每一个新元素进去之后会跟里面所有已有的元素比较,并分别根据返回的正负零来判断。(这里我不能说明的很清楚)
但你可以在compare方法第一行加入System.out.println(s1+"............"+s2);然后分别用红色和绿色代码,观察仔细的比较结果;

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1 赞一个!

查看全部评分

回复 使用道具 举报
将代码Integer value = tm.get(ch ); tm.put(ch ,cou);中ch分别换成ch[i]。是ch[i]。
回复 使用道具 举报
本帖最后由 张向辉 于 2013-1-15 12:48 编辑

不知道你颜色标注的是哪里,简单解释下你的程序为什么出现两个相同的键a的原因
毕老师在讲解TreeSet时说:treeSet集合为了提高效率,元素多了以后不会从起点开始比较,而是从折中处开始比较。
你的存入的第一个键是a,第二个键b存时会和a比较,不同则存入新的键值对,相同修改键a的值;
存入c时,c和a比返回1,再和二叉树中a的右侧的b比较,返回1,如果b的右侧还有元素再和b的右侧比较...   没有则存入c;
注意:存入b和c时,比较起点都是a;
当再存入a时,系统将比较起点修改成b键,a和b比较,返回1,a再和b的右侧键c比较返回1,c的右侧没有键了,将a作为新键存入。便出现了两个a键情况。
要想让a存入时和b键上部或者左侧的键比较,返回需返回-1,如果是1,只能和右侧键比较。
如果存入的元素足够多,也可能从e处开始比较 ,你可以试一下。

tree.JPG (9.76 KB, 下载次数: 27)

tree.JPG
回复 使用道具 举报
张向辉 发表于 2013-1-15 12:47
不知道你颜色标注的是哪里,简单解释下你的程序为什么出现两个相同的键a的原因
毕老师在讲解TreeSet时说:t ...

给力。  这就完全清楚了。  
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马