2014-02-24 98 views
1

我有一個HaspMap,它具有「文本」對象作爲鍵和「整數」對象作爲值。值實際上是我的代碼中密鑰的出現次數。所以第一次它會是1,然後不斷遞增。該代碼如下所示。添加新的鍵值對替換Java中的所有值HashMap

首先我檢查給定的「文本」對象是否存在於地圖中。如果它沒有,那麼我將它作爲一個鍵值添加到地圖中,值爲1.但是我面臨的問題是,當我通過「put」函數將新的鍵和值添加到地圖時出於某種原因Map中先前存在的鍵/值對將被替換爲新的一個。代碼如下。

public class WordPatternReducer extends Reducer<IntWritable,Text, Text, IntWritable>{ 
private IntWritable totalWordCount = new IntWritable(); 
private Map<Text,Integer> valueCount=new HashMap<Text,Integer>(); 
private Map<IntWritable,HashMap<Text,Integer>> posMap=new HashMap<IntWritable, HashMap<Text, Integer>>(); 
@Override 
public void reduce(IntWritable key, Iterable<Text> values, Context context) 
      throws IOException, InterruptedException { 
    Iterator<Text> it=values.iterator(); 
    Integer maxCountInteger=new Integer(1); 
    Text maxOccurText = null; 
    Text newval=new Text(); 
    while (it.hasNext()) { 
     newval=it.next(); 
     System.out.println("The new val outside is"+newval); 
     if (valueCount.containsKey(newval)) { 
      System.out.println("The new val inside if is"+newval); 
      valueCount.put(newval, (valueCount.get(newval)+1)); 
     } else { 
      System.out.println(newval); 
      valueCount.put(newval, 1); 
      System.out.println(valueCount.toString()); 
     } 
     maxOccurText=newval; 

} }} 

因此,現有密鑰的檢查工作,因爲它總是去else語句。但價值正在被取代。在輸出控制檯中,我得到以下輸出。

The new val outside isWelcome 
Welcome 
{Welcome=1} 
The new val outside isservice service 
{service=1, service=1} 
The new val outside isversions  versions 
{versions=1, versions=1, versions=1} 
The new val outside isto 
to 
{to=1, to=1, to=1, to=1} 
The new val outside isproviders, 
providers, 
{providers,=1, providers,=1, providers,=1, providers,=1, providers,=1} 
The new val outside isof of 
{of=1, of=1, of=1, of=1, of=1, of=1} 
The new val outside isthe the 
{the=1, the=1, the=1, the=1, the=1, the=1, the=1} 
The new val outside issome some 
{some=1, some=1, some=1, some=1, some=1, some=1, some=1, some=1} 

等..

我不想這樣。我只是想添加保留舊的Key值對。有人能讓我知道我做錯了什麼嗎?先謝謝你。

+1

文本是否實現了equals/hashCode? 看看http://stackoverflow.com/questions/18032172/why-java-uses-equals-instead-of-to-check-an-objects-presence-in-a-map/18032235#18032235 –

+0

對於這個應用程序,你應該考慮Google Guava的'Multiset';它是計數對象的專用集合。 – chrylis

回答

0

您正在映射中存儲對newval的引用。 containsKey(newval)將檢查false,因爲Text會檢查它的內容是否相同,但put調用會存儲對您重複放置在map中的相同newval的引用(它只包含讀入的最新字符串)。嘗試將映射更改爲String,Int映射並調用map.put(newval.toString())來啓動,這應該會引導您找到更好的解決方案。否則,在迭代器循環中聲明newval,以便每次在地圖中存儲新的Text對象(Text newval = it.next())。

+0

是的工作。文本是不可變對象。將對象更改爲字符串,然後開始工作。 – user3331114

0

什麼類是Text?假設1:Text不執行equals()hashCode()according to the contract。這會弄亂地圖。

假設2:Text在迭代期間是可變的和變化的。在地圖中使用字符串鍵可以解決這個問題。

+0

這裏的基本問題是「我如何調試我的程序?」一般的答案是考慮可以解釋症狀的假設,然後檢驗假設。還要問這些假設問題會造成什麼其他症狀。 – Jerry101

0

它看起來像你的Text值是可變的。什麼是Iterable values對象的實現?它是一個解析器,它重複返回相同的標記實例,並且每次調用next()時都修改它的類型和文本?如果是這樣,則需要將文本複製到一個新的不可變對象—,該對象可能只是一個String —並將該不可變令牌用作密鑰。

+0

上面顯示的代碼是Hadoop Map Reducer中Reducer的代碼。 Iterable值是Java代碼之一。 – user3331114