Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.ori.outlierserver.model; import com.ori.outlierserver.dto.Reading; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.apache.commons.lang.NullArgumentException; /** * * @author Haim */ public class DataUtil { public static enum OUTLIER_TYPE { NONE, MINOR, MAJOR } public Classifier<Reading, OUTLIER_TYPE> getOutlierClassifierFromList(final List<Reading> list) throws Throwable { if (list == null) { throw new Exception("List cannot be null"); } if (list.size() < 1) { throw new Exception("List cannot be empty"); } final double[] fences = getOutlierBounderysFromLits(list); return new Classifier<Reading, OUTLIER_TYPE>() { @Override public OUTLIER_TYPE classify(final Reading object) throws Throwable { if (object == null) { throw new NullArgumentException("Object cannot be null"); } double median_value = object.getMedian_value(); if (median_value < fences[0] || median_value > fences[3]) { return OUTLIER_TYPE.MAJOR; } if (median_value >= fences[0] && median_value < fences[1] || median_value >= fences[2] && median_value < fences[3]) { return OUTLIER_TYPE.MINOR; } return OUTLIER_TYPE.NONE; } }; } private double[] getOutlierBounderysFromLits(List<Reading> list) { if (list == null) { return null; } if (list.size() == 1) { double[] arrayForOne = new double[4]; Arrays.fill(arrayForOne, list.get(0).getMedian_value()); return arrayForOne; } List<Double> values = new ArrayList<>(); list.stream().forEach((Reading r) -> { values.add(r.getMedian_value()); }); int theSize = values.size(); if (theSize == 1) { return new double[] {}; } Collections.sort(values); boolean isEven = theSize % 2 == 0; double medianValue = findMedianValue(values); List<Double> lowerHalf = new ArrayList<>(); List<Double> upperHalf = new ArrayList<>(); for (Double d : values) { if (d.compareTo(medianValue) == -1) { lowerHalf.add(d); } } for (Double d : values) { if (d.compareTo(medianValue) >= 0) { upperHalf.add(d); } } double medianLow = findMedianValue(lowerHalf); double medianHigh = findMedianValue(upperHalf); double minorFenceDelta = (medianHigh - medianLow) * 1.5; double majorFenceDelta = (medianHigh - medianLow) * 3; return new double[] { medianLow - majorFenceDelta, medianLow - minorFenceDelta, medianHigh + minorFenceDelta, medianHigh + majorFenceDelta }; } /** * Helper method, assuming list is sorted * * @param list the list to look in * @return median value for this list */ private double findMedianValue(List<Double> list) { int theSize = list.size(); if (theSize == 1) { return list.get(0); } boolean isEven = theSize % 2 == 0; int midPoint = (theSize - (theSize % 2)) / 2; double medianValue = list.get(midPoint); if (isEven) { medianValue += list.get(midPoint - 1); medianValue /= 2; } return medianValue; } }