2010-09-13 2 views
1

Я работаю над проектом Java, в котором у меня есть метод геттер ниже в классе TextAnalyzer:только в состоянии использовать геттер раз

public Hashtable<String, Double> getTotalFeatureOccurances() { 
    return(feat_occur_total); 
}//getTotalFeatureOccurances 

Я также приватную переменную класса:

private Hashtable<String, Double> feat_occur_total; 

Я использую геттер, добавляю больше терминов к хэшу, а затем хочу снова получить хэш, но он всегда возвращается пустым. Хуже того, если я не добавляю или не удаляю что-либо из хэша, но делаю два, я все равно получаю и пустым хешем второй раз.

Вот мой код в основной:

TextAnalyzer ta = new TextAnalyzer(); 
     feat_occur_cat = ta.wordOccurancesCount(text, features); 
     feat_occur_total = ta.getTotalFeatureOccurances(); 

     Enumeration<Double> e = feat_occur_total.elements(); 
     while(e.hasMoreElements()) { 
      System.out.println(e.nextElement()); 
     }//while 

     feat_occur_total.clear(); 
     feat_occur_total = ta.getTotalFeatureOccurances(); 

     e = feat_occur_total.elements(); 
     System.out.println("\n\nSECOND GET\n\n"); 
     while(e.hasMoreElements()) { 
      System.out.println(e.nextElement()); 
     }//while 

Я получаю результат:

2.0 
1.0 
5.0 
1.0 
1.0 
3.0 
2.0 
3.0 


SECOND GET 

Вот весь класс:

public class TextAnalyzer { 

    TextAnalyzer() { 
     this.feat_occur_total = new Hashtable<String, Double>(); 
    } 

    public String[][] wordOccurancesCount(String text, Vector<String> features) { 
     String[][] occur = new String[features.size()][features.size()]; 

     for(int ndx=0; ndx<features.size(); ndx++) { 
      int count=0; 

      Pattern p = Pattern.compile("(?:^|\\s+|\\()\\s*(" + features.elementAt(ndx).trim() + ")\\w*(?:,|\\.|\\)|\\s|$)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.CANON_EQ); 
      Matcher m = p.matcher(text); 
      m.usePattern(p); 

      while(m.find()) 
       count++; 

      occur[ndx][0] = features.elementAt(ndx); 
      occur[ndx][1] = String.valueOf(count); 

      if(this.feat_occur_total.containsKey(features.elementAt(ndx))) { 
       double temp = this.feat_occur_total.get(features.elementAt(ndx)); 
       temp += count; 
       this.feat_occur_total.put(features.elementAt(ndx), temp); 
      }//if 
      else { 
       this.feat_occur_total.put(features.elementAt(ndx), Double.valueOf(count)); 
      }//else 
     }//for 

     return(occur); 
    }//word 

    public Hashtable<String, Double> getTotalFeatureOccurances() { 
     return(feat_occur_total); 
    }//getTotalFeatureOccurances 

    private Hashtable<String, Double> feat_occur_total; 

}//TextAnalyzer 
+0

Btw Hashtable устарел - вместо этого вместо HashMap следует использовать однопоточный код или ConcurrentHashMap в противном случае. –

+0

Возможно, это просто педантичность, но если вы создадите хеш-таблицу и никогда не изменяете личную ссылку в своем классе, она также должна быть «окончательной». Это четко указывает ваше намерение пользователям класса, а конечные переменные позволяют компилятору выполнять оптимизации, которые он в противном случае не может выполнять. – 2010-09-13 19:44:35

ответ

5

Это:

feat_occur_total.clear(); 

Очищает Hashtable. Поскольку вы вернули ссылку на исходную переменную, вы сами очистили Hashtable, а не копию. Поэтому возвращение его снова вернет очищенный Hashtable.

+1

Это 'Hashtable' с маленьким' t' :) – BalusC

+0

Огромная помощь. Я не понимал, что возвращает ссылку на Hashtable, очень полезную для понимания. Спасибо за помощь. – user387049

1

Ваш получатель возвращает ссылку на приватное поле feat_occur_total, а не на копию. После этого как ссылка TextAnalyzer.feat_occur_total, так и ссылка, возвращаемая геттером, относятся к тому же экземпляру. Вы вызываете clear(), используя ссылку, полученную от получателя, которая очищает карту, на которую ссылаются как фрагмент кода вверху, так и пример TextAnalyzer.

Смежные вопросы