簡體   English   中英

原因不明的Java Hashmap行為

[英]Unexplained Java Hashmap Behavior

在下面的代碼中,我創建了一個hashmap來存儲名為Datums的對象,它包含一個String(位置)和一個count。 不幸的是,代碼給出了非常奇怪的行為。

            FileSystem fs = FileSystem.get(new Configuration());
            Random r = new Random();
            FSDataOutputStream fsdos = fs.create(new Path("error/" + r.nextInt(1000000)));

            HashMap<String, Datum> datums = new HashMap<String, Datum>();
            while (itrtr.hasNext()) {
                Datum next = itrtr.next();
                synchronized (datums) {
                    if (!datums.containsKey(next.location)) {
                        fsdos.writeUTF("INSERTING: " + next + "\n");
                        datums.put(next.location, next);
                    } else {
                    } // skit those that are already indexed 
                }
            }
            for (Datum d : datums.values()) {
                fsdos.writeUTF("PRINT DATUM VALUES: " + d.toString() + "\n");
            }

hashmap將字符串作為鍵。

這是我在錯誤文件中得到的輸出(示例):

INSERTING: (test.txt,3)

INSERTING: (test2.txt,1)

PRINT DATUM VALUES: (test.txt,3)

PRINT DATUM VALUES: (test.txt,3)

The correct output for the print should be:
INSERTING: (test.txt,3)

INSERTING: (test2.txt,1)

PRINT DATUM VALUES: (test.txt,3)

PRINT DATUM VALUES: (test2.txt,1)

以test2.txt作為位置的Datum發生了什么? 為什么它會被test.txt取代?

基本上,我不應該兩次看到相同的位置。 (這就是!datums.containsKey正在檢查的內容)。 不幸的是,我的行為非常奇怪。

順便說一下,這是在Hadoop上的減速器。

我嘗試將同步放在這里,以防它在多個線程中運行,據我所知,它不是。 不過,同樣的事情發生了。

這不是地圖的問題,而是代碼datums.put(next.location,next); insert作為后面的chnaged的值引用:)這就是為什么最后地圖中的所有值都等於地圖中最后處理的數據

根據這個答案, Hadoop的迭代器總是返回相同的對象,而不是創建一個新的對象,每次循環返回。

因此,保持對迭代器返回的對象的引用是無效的,並且將產生令人驚訝的結果。 您需要將數據復制到新對象:

        while (itrtr.hasNext()) {
            Datum next = itrtr.next();
            // copy any values from the Datum to a fresh instance
            Datum insert = new Datum(next.location, next.value);
            if (!datums.containsKey(insert.location)) {
                datums.put(insert.location, insert);
            }
        }

以下是對Hadoop Reducer文檔的引用,該文檔證實了這一點:

該框架將重用傳遞給reduce的鍵和值對象,因此應用程序應克隆他們想要保留副本的對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM