黑马程序员技术交流社区

标题: 报空指针异常,是为什么?请告诉实际发生的原理 [打印本页]

作者: 羽狼之翼    时间: 2015-1-28 21:34
标题: 报空指针异常,是为什么?请告诉实际发生的原理
public class Demo4 {
        public static void main(String[] args) {
                Map<String, Student> map = new TreeMap<String, Student>(new Comparator<String>()
                                {

                        @Override
                        public int compare(String s1, String s2) {
                                return -1;
                        }
                       
                });
               
                map.put("abc", new Student("1", "11"));
                map.put("bac", new Student("2", "22"));
                map.put("cba", new Student("3", "33"));
                map.put("cab", new Student("4", "44"));
                map.put("b", new Student("5", "55"));
                map.put("a", new Student("5", "55"));
                map.put("bca", new Student("6", "66"));               

                Set<String> set = map.keySet();
                for (String key : set) {
                        Student s = map.get(key);
                        System.out.println(s.getName() + "***" + s.getId());
                }
        }
}

public class Student {
        private String id;
        private String name;

        public Student() {
                super();
        }

        public Student(String id, String name) {
                super();
                this.id = id;
                this.name = name;
        }

        public String getId() {
                return id;
        }

        public void setId(String id) {
                this.id = id;
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        @Override
        public String toString() {
                return "Student [id=" + id + ", name=" + name + "]";
        }
       
}


作者: Gonnaloveu    时间: 2015-1-28 22:44
本帖最后由 Gonnaloveu 于 2015-1-29 16:22 编辑

不行了才疏学浅实在想不明白原因,我只能告诉你我测试出是比较器的问题(把比较器注释掉就正常),如果你知道为什么请告诉我一声...当然我要是明白了也会告诉你的.
作者: gzy    时间: 2015-1-28 23:00
代码有点乱没看清
作者: weiwei10153    时间: 2015-1-29 00:15
这个代码本身是没有错的....

以下是我的一些想法,不一定完全正确,仅作参考意见
      这个代码出现了一种特殊情况,通过查询map集合通过keySet转换为set集合后,set集合的长度是7,并且可以看到set集合中存储的键值都是正确的.假如通过map集合通过entrySet转换为set集合后,通过遍历Map.Entry对象中的每一个键和每一个值,发现不为null,这里至少证明map中存储的元素以及前面的一些比较器都是没有问题的.
      但是在map集合中通过键值获取相应的值的时候,会出现一种特殊情况.在API中,在map集合的get方法中,有下面的一段说明,
      返回 null 值并不一定 表明映射不包含该键的映射关系;也可能此映射将该键显式地映射为 null。可以使用containsKey 操作来区分这两种情况。

      于是,我尝试通过下面这种方法进行判断:
       Set<String> set = map.keySet();
       for (String key : set) {
             System.out.println(key + "..." + map.containsKey(key));
       }
      发现打印的结果为:
      bca...false
      a...false
      b...false
      cab...false
      cba...false
      bac...false
      abc...false
      我认为可能是出现了这种特殊的情况,
      以上是我的个人看法,也希望大神能够帮忙解答.......

     至于解决的方法,通过entrySet转换获取元素是正确的


作者: play1369    时间: 2015-1-29 00:37
确实是用entrySet方法可以
作者: kenfine    时间: 2015-1-29 07:20
{:3_62:}我的思维完全凌乱了
作者: kenfine    时间: 2015-1-29 07:39
上述代码直接把TreeSet改成HashSet也行,可用keySet,静待大神解决
作者: 白小马    时间: 2015-1-29 08:19
初学者表示看不懂 压力山大啊
作者: cly成子    时间: 2015-1-29 09:53
看不大懂代码!!
作者: mengxiang1993    时间: 2015-1-29 10:02
初学者,学习学习
作者: lwh316658735    时间: 2015-1-29 16:41
本帖最后由 lwh316658735 于 2015-1-29 16:42 编辑

。。。。
作者: kenfine    时间: 2015-1-29 20:50
http://bbs.itheima.com/thread-37180-1-1.html
这个问题我在其他的板块上找到了,那个原因不甚明了,不过,将比较器中的返回-1改为return s1.compareTo(s2);就没有了空指针异常了。
以下是上面链接的原话:
因为你的comparator写的有问题,你每次都返回-1,虽然实现了按输入顺序排序,但也带来了很多问题。比如,可以输入重复元素,因为每次比较都不等;还有一个就是你现在程序出现的问题,每次当你从新建的Set集合取出一个key(stu)去找它对应的值时,它要先将这个key跟tm的每个key比较,由于比较器返回的都是1,没有==0,即相等的情况,所以每次返回的都是null了。
作者: 流行VS泪痕    时间: 2015-1-29 22:08
表示不太明白?这不是Java把,应该是与C有关的吧!
作者: 还是菜鸟    时间: 2015-1-29 22:43
学习学习
作者: 羽狼之翼    时间: 2015-2-4 21:39
kenfine 发表于 2015-1-29 20:50
http://bbs.itheima.com/thread-37180-1-1.html
这个问题我在其他的板块上找到了,那个原因不甚明了,不过 ...

貌似这个回答是可以接纳的,感谢朋友!
作者: kenfine    时间: 2015-2-4 22:00
{:3_62:}具体的原理我也不是很清楚,有时间翻翻JDK源代码看看,哈哈,只希望能看的懂{:3_62:}
作者: duxubo    时间: 2015-2-4 22:52
你的代码太混乱了,看不懂你是想根据键 还是 id 还是姓名 排序 但是你的比较器写错了,字符串的比较是o1.compareTo(o2)
作者: yk942608890    时间: 2015-2-5 09:04
路过,学习




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2