Java tutorial
/** * Copyright 2013 BigML * Licensed under the Apache License, Version 2.0 * http://www.apache.org/licenses/LICENSE-2.0 */ package com.bigml.histogram; import java.io.IOException; import java.text.DecimalFormat; import org.json.simple.JSONArray; public class Bin<T extends Target> implements Comparable<Bin> { public Bin(double mean, double count, T target) { /* Hack to avoid Java's negative zero */ if (mean == 0d) { _mean = 0d; } else { _mean = mean; } _count = count; _target = target; } @SuppressWarnings("unchecked") public Bin(Bin<T> bin) { this(bin.getMean(), bin.getCount(), (T) bin.getTarget().clone()); } @SuppressWarnings("unchecked") public JSONArray toJSON(DecimalFormat format) { JSONArray binJSON = new JSONArray(); binJSON.add(Utils.roundNumber(_mean, format)); binJSON.add(Utils.roundNumber(_count, format)); _target.addJSON(binJSON, format); return binJSON; } public double getCount() { return _count; } public double getMean() { return _mean; } public double getWeight() { return _mean * (double) _count; } public T getTarget() { return _target; } @SuppressWarnings("unchecked") public void sumUpdate(Bin bin) { _count += bin.getCount(); _target.sum(bin.getTarget()); } @SuppressWarnings("unchecked") public void update(Bin bin) throws BinUpdateException { if (_mean != bin.getMean()) { throw new BinUpdateException("Bins must have matching means to update"); } _count = bin.getCount(); _target = (T) bin.getTarget(); } @Override public String toString() { return toJSON(new DecimalFormat(Histogram.DEFAULT_FORMAT_STRING)).toJSONString(); } /** * Append a text representation of this bin to the specified appendable. * * @param appendable appendable to append to, must not be null * @param format decimal format, must not be null * @throws IOException if an error occurs */ public void appendTo(final Appendable appendable, final DecimalFormat format) throws IOException { if (appendable == null) { throw new NullPointerException("appendable must not be null"); } if (format == null) { throw new NullPointerException("format must not be null"); } appendable.append(format.format(_mean)); appendable.append("\t"); appendable.append(format.format(_count)); appendable.append("\t"); _target.appendTo(appendable, format); appendable.append("\n"); } @SuppressWarnings("unchecked") public Bin<T> combine(Bin<T> bin) { double count = getCount() + bin.getCount(); double mean = (getWeight() + bin.getWeight()) / (double) count; T newTarget = (T) _target.init(); newTarget.sum(_target); newTarget.sum(bin.getTarget()); return new Bin<T>(mean, count, newTarget); } @Override @SuppressWarnings("unchecked") public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Bin<T> other = (Bin<T>) obj; return Double.doubleToLongBits(_mean) == Double.doubleToLongBits(other._mean); } @Override public int hashCode() { int hash = 3; hash = 97 * hash + (int) (Double.doubleToLongBits(_mean) ^ (Double.doubleToLongBits(_mean) >>> 32)); return hash; } private T _target; private final double _mean; private double _count; public int compareTo(Bin o) { return Double.compare(getMean(), o.getMean()); } }