How to calculate mean, median, mode and range from a set of numbers

后端 未结 7 1578
闹比i
闹比i 2020-12-07 13:34

Are there any functions (as part of a math library) which will calculate mean, median, mode and range from a set of numbers.

7条回答
  •  佛祖请我去吃肉
    2020-12-07 13:52

    Yes, there does seem to be 3rd libraries (none in Java Math). Two that have come up are:

    http://opsresearch.com/app/

    http://www.iro.umontreal.ca/~simardr/ssj/indexe.html

    but, it is actually not that difficult to write your own methods to calculate mean, median, mode and range.

    MEAN

    public static double mean(double[] m) {
        double sum = 0;
        for (int i = 0; i < m.length; i++) {
            sum += m[i];
        }
        return sum / m.length;
    }
    

    MEDIAN

    // the array double[] m MUST BE SORTED
    public static double median(double[] m) {
        int middle = m.length/2;
        if (m.length%2 == 1) {
            return m[middle];
        } else {
            return (m[middle-1] + m[middle]) / 2.0;
        }
    }
    

    MODE

    public static int mode(int a[]) {
        int maxValue, maxCount;
    
        for (int i = 0; i < a.length; ++i) {
            int count = 0;
            for (int j = 0; j < a.length; ++j) {
                if (a[j] == a[i]) ++count;
            }
            if (count > maxCount) {
                maxCount = count;
                maxValue = a[i];
            }
        }
    
        return maxValue;
    }
    

    UPDATE

    As has been pointed out by Neelesh Salpe, the above does not cater for multi-modal collections. We can fix this quite easily:

    public static List mode(final int[] numbers) {
        final List modes = new ArrayList();
        final Map countMap = new HashMap();
    
        int max = -1;
    
        for (final int n : numbers) {
            int count = 0;
    
            if (countMap.containsKey(n)) {
                count = countMap.get(n) + 1;
            } else {
                count = 1;
            }
    
            countMap.put(n, count);
    
            if (count > max) {
                max = count;
            }
        }
    
        for (final Map.Entry tuple : countMap.entrySet()) {
            if (tuple.getValue() == max) {
                modes.add(tuple.getKey());
            }
        }
    
        return modes;
    }
    

    ADDITION

    If you are using Java 8 or higher, you can also determine the modes like this:

    public static List getModes(final List numbers) {
        final Map countFrequencies = numbers.stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    
        final long maxFrequency = countFrequencies.values().stream()
                .mapToLong(count -> count)
                .max().orElse(-1);
    
        return countFrequencies.entrySet().stream()
                .filter(tuple -> tuple.getValue() == maxFrequency)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }
    

提交回复
热议问题