我对Java HashMap有一些奇怪的和意想不到的行为,仅仅用于测试的一部分代码。我可以有一个非空的hashmap,其中没有任何键吗?
要尽量将其存储在会议上,我使用if{}else{}
声明,但我发现自己与我的应用程序错误之前一个唯一的ID设置为一个对象。为测试目的,产生
的ID,因为目前没有数据库实际存储的数据,其被存储在会话在其间。
这里是我的代码片段:
...
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。
所以我想知道是否有可能一个地图是非空的没有任何价值(显然,是的,但我也问自己是如何)以及它怎么没有返回后为null它完全被清空了?
尽管我得到它在new
声明后为空,怎么会在session.getAttribute()
调用之后呢?这似乎很明显,因为没有地图存储在会话中,但同时它似乎很奇怪,因为没有new
声明。