【发布时间】:2013-02-27 09:55:32
【问题描述】:
我在 java HashMap 上遇到了一个奇怪且意外的行为,在仅用于测试的部分代码上。
为了在将对象存储到会话中之前尝试为其设置唯一 ID,我使用了 if{}else{} 语句,但我发现自己的应用程序出现错误。
ID 是出于测试目的而生成的,因为目前没有数据库来实际存储数据,同时存储在 session 中。
这是我的sn-p代码:
...
HttpSession session = request.getSession();
Map<Integer, Booking> bookings = (HashMap<Integer, Booking>) session.getAttribute(SESSION_BOOKINGS);
// Generates ID
if (bookings == null)
{
bookings= new HashMap<Integer, Booking>();
identificator = 1;
}
else
{
Object[] arrayKeys = (Object[]) bookings.keySet().toArray();
Arrays.sort(arrayKeys);
identificator = (Integer) arrayKeys[arrayKeys.length - 1] + 1;
}
...
//... The rest is setting the ID to the current worked on booking,
//... putting the ID/booking pair in the bookings map
//... and storing the map in session, which worked fine
当地图只包含一个预订时,删除地图中的预订后出现错误。当我在那之后尝试再注册一个时,我收到了一个错误,错误原因如下java.lang.ArrayIndexOutOfBoundsException: -1 和链接到我的else 语句的最后一行的跟踪:identificator = (Integer) arrayKeys[arrayKeys.length - 1] + 1;
所以:
arrayKeys.length -1 == -1 // true- 表示
arrayKeys.length == 0 // true 这又意味着来自
Map<Integer,Booking> bookings的keySet()是空的然而测试没有进入
if语句
另一方面,在一个全新的会话中(在重新启动浏览器或注销并再次登录之后),测试确实按预期输入了 if 语句。
测试后,我将状态从(bookings==null)更改为
到(bookings==null || bookings.isEmpty()).
进一步的测试表明,在新会话上注册预订时,仅使用 (bookings.isEmpty() 会导致 NPE。
所以我想知道一个 Map 是否有可能是非空的,其中没有任何值(显然,是的,但我也在问自己如何)以及它为什么在它之后没有返回空完全清空了?
虽然我知道在new 语句之后它是空的,但在session.getAttribute() 调用之后它是怎么来的?看起来很明显,因为 session 中还没有存储 Map,但同时因为没有 new 语句,这看起来很奇怪。
【问题讨论】:
标签: java jakarta-ee map hashmap key