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

Integer i =  null;
System.out.println(map.get(str)+i);
也报异常
回复 使用道具 举报

map.put(str, false? i :(map.get(str) + (false? 1 : i)) );
map.put(str, true? i :(map.get(str) + (false? 1 : i)) );
map.put(str,  i );

通过验证知道,在i=null的时候,上面两句无论都是true还是都是false结果都是挂。
但是第三句可以知道map.put直接传入i是没有问题的,那么,我们就可以知道三元
运算符在运算的时候一定是先执行到了后面的语句(map.get(str) + (false? 1 : i))也就
是三元运算符运算后有可能输出的结果,你那么写等效于下面的这三句
            Integer x= (i==null? 1 : i);
            Integer a=(map.get(str) + x);//i是null时将会在这里挂掉
            map.put(str, map.get(str)==null ? i :a);

需要先知道结果才能继续运算,所以你这个代码在运行到上面第二行那里就挂了。
回复 使用道具 举报
王晓斌 发表于 2013-1-20 22:38
问题应该是出在最后一句,我们的目的是把键值对放入集合中,也就是说集合中现在还没有这个键值对~~~那么 ...

取没有的,会返回null
回复 使用道具 举报
黄锦成 发表于 2013-1-20 23:44
这个没问题,null是可以赋给引用类型的,我们平时在定义引用类型变量时可以写成 private String str = nu ...

是的。我也搞错了的。嗯。。。估计是NULL在下面被随机了。呵呵。
回复 使用道具 举报
问题出在map.get(str)吧,进行这项操作时集合中还不存在该键值对,所以进行map.get(str)操作会返回null。你打印map.get(str)结果会是null,但该null不是表示map.get(str)的值,而是表示操作的键值对不存在,你可以打印它得到null,但是不能将它用于运算,否则会抛出NullPointerException!
验证了一下:
class Demo2
{
        public static void main(String[] args)
        {
               
                Map<String, Integer> map = new HashMap<String, Integer>();
               
                String str = "x";
                Integer i = Math.random()*10 > 7? 5 : null;

                System.out.println(map.get(str));//打印map.get(str)没问题
                Integer j = map.get(str)+5; //将map.get(str)用于运算则报NullPointerException
        }
}
回复 使用道具 举报
舒远 黑马帝 2013-1-21 09:43:52
26#
本帖最后由 舒远 于 2013-1-21 09:50 编辑

map.put(str, map.get(str) == null ? i : Integer.valueOf(map.get(str) + (i == null ? 1 : i)));
最后一句话必须改成如上代码,才能避免空指针的出现。
三元表达式必须保证冒号两边的表达式运算结果的类型一致。
回复 使用道具 举报
我觉得原因应该是在这里:
  1. map.put(str, map.get(str) == null ? i : (map.get(str) + (i == null ? 1: i)));
复制代码
map.get(str)+....
当 i 为null时,三元运算符后面的值是null+1,这时候jvm可能尝试调用了null.intValue()+1进行运算,于是报了异常

回复 使用道具 举报
貌似楼主知道正解哎,  我看上面有人回答到点了,楼主没有采纳哎
问题是三元运算符里的 i  指向了NULL造成的
Integer i = null;
true ? i : 其他值;  这样就出现空指针异常。
回复 使用道具 举报
舒远 发表于 2013-1-21 09:43
map.put(str, map.get(str) == null ? i : Integer.valueOf(map.get(str) + (i == null ? 1 : i)));
最后一 ...


也可以如下:
map.put(str, map.get(str) == null ? i : (Integer)(map.get(str) + (i == null ? 1 : i)));

再问:
(map.get(str) + (i == null ? 1 : i)),这个表达式为什么返回类型是int,分析一下
回复 使用道具 举报
楼主貌似知道正解哎 上面有人提到问题所在了,楼主没有采纳啊
问题就出在三元运算符里 i  变量 i 指向了null
Integer i = null ;
true ? i : 其他值;  此时会报空指针异常
回复 使用道具 举报
张向辉 发表于 2013-1-21 12:19
貌似楼主知道正解哎,  我看上面有人回答到点了,楼主没有采纳哎
问题是三元运算符里的 i  指向了NULL造成 ...

呵呵~~~
大多数都知道i=null或者map.get(str)=null,但为什么会报空指针异常,这没说出来,刚看到有一个说出来了
回复 使用道具 举报
舒远 黑马帝 2013-1-21 12:27:17
32#
张向辉 发表于 2013-1-21 12:24
楼主貌似知道正解哎 上面有人提到问题所在了,楼主没有采纳啊
问题就出在三元运算符里 i  变量 i 指向了nul ...

问题根本不在这。。多写点代码测试一下就知道了
回复 使用道具 举报
舒远 黑马帝 2013-1-21 12:28:36
33#
我是菜鸟 发表于 2013-1-21 12:19

也可以如下:
map.put(str, map.get(str) == null ? i : (Integer)(map.get(str) + (i == null ? 1 :  ...

i == null ? 1 : i
这个表达式的类型是int,因为i为null,返回的是1,默认int,这里没有自动装箱的机制。
回复 使用道具 举报
舒远 发表于 2013-1-21 12:28
i == null ? 1 : i
这个表达式的类型是int,因为i为null,返回的是1,默认int,这里没有自动装箱的机制。 ...

远哥 说的有道理   对于他这道题来说想深了   我测试了他的程序  在 i  不等于null 的情况下不会出异常
问题就出在这
map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));
map.get(str)==null  为ture
第一个表达式是 i
第二个表达式也可能出错,不重要了,不执行
i 为 null 就空指针异常了  
这是简单点的考虑
回复 使用道具 举报
舒远 黑马帝 2013-1-21 12:50:35
35#
张向辉 发表于 2013-1-21 12:41
远哥 说的有道理   对于他这道题来说想深了   我测试了他的程序  在 i  不等于null 的情况下不会出异常
...

你还是没理解:
map.put(str,null);这句话不会报错的。
回复 使用道具 举报
本帖最后由 方寅生 于 2013-1-21 13:06 编辑

map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));
这一句之前加一句
i=i==null? 1 : i;
然后map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));;改成
map.put(str, map.get(str)==null ? i : (map.get(str) + i));
回复 使用道具 举报
舒远 发表于 2013-1-21 12:28
i == null ? 1 : i
这个表达式的类型是int,因为i为null,返回的是1,默认int,这里没有自动装箱的机制。 ...

按你说这个表达式的类型是int,因为i为null,返回的是1,默认int,不要忘记了前面还有一个表达式map.get(str),最后的结果是null+1,null需要拆箱,也会报错的
对于整个表达式,map.put(str, map.get(str) == null ? i : (map.get(str) + (i == null ? 1 : i)));表达式3( (map.get(str) + (i == null ? 1 : i)))是执行不到的

有其他人已经在提问这问题了 关于关于三元运算符
回复 使用道具 举报
太热闹了 哇唔   这样的问题 以后我必须加分!
回复 使用道具 举报
public static void main(String[] args)
        {
                Map<String, Integer> map = new HashMap<String, Integer>();
                String str = "x";
                Integer i = Math.random()*10 > 7? 5 : null;
                System.out.println(i);
     标记: map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));
        }

分析下流程吧:
i=5的话,没问题,不考虑,关键是i=null的时候。
i=null的时候,标记前面的代码没问题,现在执行标记处的代码,首先判断外层的三元运算符,
map.get(str)==null为真,于是该表达式的值为i,但是i的值被该三元运算符的表达式3给修改了,
于是要得到i的值,jvm只能执行表达式3,运行map.get(str),结果为null,这时候jvm并不会报异常,
还要继续运算里面的三元运算符的值,求出i=1,也没问题,然后要计算null+1的值,这时候jvm根据
map的定义的类型得出null+1的值应该是Integer类型,于是会尝试将null解包成int类型进行运算,
这里有可能调用的是null.intValue()方法,但是null里面根本没有这个方法,这时候空指针异常出现了。

这应该就是问题的位置和原因了吧。




回复 使用道具 举报
本帖最后由 赵彦辉 于 2013-1-21 13:41 编辑

我测试的是这两句抛的空指针异常

  1.           public static void main(String[] args)
  2.       {
  3.               Map<String,Integer>  map = new HashMap<String,Integer>();
  4.               String str = "x";
  5. //             Integer i = Math.random()*10 > 7? 5 : null;
  6. //              System.out.println(i);
  7.               map.put(str, 5);
  8.               map.put(str,null);
  9.              map.put(str,5 + map.get(str));
  10.              map.put(str, 1 + map.get(str));
  11. //             map.put(str, map.get(str)==null ? i : (map.get(str) + (i==null? 1 : i)));
  12.           /*
  13.             map.get(str)==null      i = 5
  14.             map.get(str) !=null      5 + map.get(str)
  15.             
  16.             map.get(str)==null      i = null
  17.             map.get(str) !=null     1 + map.get(str)
  18.             */
  19.              Set<String> keySet = map.keySet();
  20.               for(Iterator<String> it = keySet.iterator();it.hasNext();)
  21.               {
  22.                      String str1 = it.next();
  23.                      System.out.println(str1);
  24.                      System.out.println(map.get(str));
  25.               }
  26.       }
复制代码
map.put(str,5 + map.get(str));
map.put(str, 1 + map.get(str));
请看这两句代码:map.get(str) != null, 那么键所对应的值就为 5 + map.get(str)或者 1 + map.get(str)
我测试的时候就只有这两句抛空指针异常,这个时候具体的键对应的值往Map集合中存放的时候会出错,注释掉这两句程序就OK,
不知道我的答案是不是正解,大家讨论

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