code: package cc.mallet.types;
  
  /** Efficient, compact, incremental counting of features in an alphabet. */
  public class FeatureCounter 
  {
  	Alphabet alphabet;
  	gnu.trove.TIntIntHashMap featureCounts;
  	
  	public FeatureCounter (Alphabet alphabet) {
  		this.alphabet = alphabet;
  		featureCounts = new gnu.trove.TIntIntHashMap();
  	}
  	
  	public int increment (Object entry) {
  		return featureCounts.adjustOrPutValue(alphabet.lookupIndex(entry), 1, 1);
  	}
  
  	public int increment (Object entry, int incr) {
  		return featureCounts.adjustOrPutValue(alphabet.lookupIndex(entry), incr, incr);
  	}
  
  	public int increment (int featureIndex) {
  		if (featureIndex < 0 || featureIndex > alphabet.size())
  			throw new IllegalArgumentException ("featureIndex "+featureIndex+" out of range");
  		return featureCounts.adjustOrPutValue(featureIndex, 1, 1);
  	}
  
  	public int increment (int featureIndex, int incr) {
  		if (featureIndex < 0 || featureIndex > alphabet.size())
  			throw new IllegalArgumentException ("featureIndex "+featureIndex+" out of range");
  		return featureCounts.adjustOrPutValue(featureIndex, incr, incr);
  	}
  	
  	
  	public int get (int featureIndex) {
  		if (featureIndex < 0 || featureIndex > alphabet.size())
  			throw new IllegalArgumentException ("featureIndex "+featureIndex+" out of range");
  		return featureCounts.get (featureIndex);
  	}
  
  	/** Unlike increment(Object), this method does not add the entry to the Alphabet if it is not there already. */
  	public int get (Object entry) {
  		int fi = alphabet.lookupIndex(entry, false);
  		if (fi == -1)
  			return 0;
  		else
  			return featureCounts.get (fi);
  	}
  	
  	public int put (int featureIndex, int value) {
  		if (featureIndex < 0 || featureIndex > alphabet.size())
  			throw new IllegalArgumentException ("featureIndex "+featureIndex+" out of range");
  		return featureCounts.put (featureIndex, value);
  	}
  	
  	public int put (Object entry, int value) {
  		return featureCounts.put (alphabet.lookupIndex(entry), value);
  	}
  
  	
  	public FeatureVector toFeatureVector () {
  		int[] indices = featureCounts.keys();
  		double[] values = new double[indices.length];
  		for (int i = 0; i < indices.length; i++)
  			values[i] = featureCounts.get(indices[i]);
  		return new FeatureVector (alphabet, indices, values);
  	}
  	
  	public RankedFeatureVector toRankedFeatureVector () {
  		int[] indices = featureCounts.keys();
  		double[] values = new double[indices.length];
  		for (int i = 0; i < indices.length; i++)
  			values[i] = featureCounts.get(indices[i]);
  		return new RankedFeatureVector (alphabet, indices, values);
  	}
  	
  }
  