2013-02-27 46 views
0

我對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;

所以:

  1. arrayKeys.length -1 == -1 // true
  2. 這意味着arrayKeys.length == 0 // true
  3. 這又意味着從Map<Integer,Booking> bookings所述keySet()是空

  4. 但測試沒有進入if聲明

在另一方面,在一個全新的會話(或重新啓動瀏覽器或重新登錄並在後),測試沒有進入if語句作爲預期。

經過測試,我將自己的狀況從(bookings==null)
改爲(bookings==null || bookings.isEmpty())
進一步的測試表明,只使用(bookings.isEmpty()在新會話中註冊預訂時導致NPE。

所以我想知道是否有可能一個地圖是非空的沒有任何價值(顯然,是的,但我也問自己是如何)以及它怎麼沒有返回後爲null它完全被清空了?

儘管我得到它在new聲明後爲空,怎麼會在session.getAttribute()調用之後呢?這似乎很明顯,因爲沒有地圖存儲在會話中,但同時它似乎很奇怪,因爲沒有new聲明。

回答

1

如果

if (bookings == null) 

是真實的,比你沒有一個地圖(這是從空地圖不同)。

如果執行else塊時,它是指地圖參考。你對地圖中元素的數量一無所知。你可能想是這樣的:

if (bookings == null) 
{ 
    bookings= new HashMap<Integer, Booking>(); 
    identificator = 1; 
} else if (bookings.isEmpty()) 
{ 
    identificator = 1; 
} 
else 
{ 
    identificator = Collections.max(bookings.keySet()) + 1; 
} 

要回答這個問題:

怎麼就沒有回零後,這是完全清空?

看看這段代碼:

Map<Integer, Booking> map = new HashMap<>(); 

我從來沒有進入任何鍵/值對進入地圖,所以它是空的。這與我將一些鍵/值對放入其中的狀態相同,然後再將其刪除。 map爲空,但沒有理由爲null。如果它是null我們未來不能再添加任何東西。

1

A HashMap可以是null(如果未初始化)或空(如果初始化但沒有輸入對象)。 從地圖中刪除對象將其返回到「空」狀態(並且而不是null)。

new聲明分配內存的對象,並創建爲空HashMap(和空)

1

作爲並且是是完全不同的概念。當變量(引用類型)爲空時,它指向無處。你根本沒有HashMap。你只需要一個空的指針(不是空的HashMap)。您使用bookings = new HashMap<Integer, Booking>()創建新的HashMap。之後,你有一個HashMap。你有一個HashMap,但它裏面沒有任何東西。

此外,當您從HashMap刪除所有的元素,它成爲,不。要做到這一點null,你必須明確這樣做:

bookings = null; 
相關問題