patternjavaMinor
Calculate "average", "median" and "percentile" from a long array
Viewed 0 times
percentilearraylongaveragecalculateandfrommedian
Problem
I have this method which calculates the average, median and percentile information given a long array of numbers. Is there any better and efficient way to do the same?
public static double median(long[] numbers) {
Arrays.sort(numbers, 0, numbers.length);
int middle = numbers.length / 2;
if (numbers.length % 2 == 1) {
return numbers[middle];
} else {
return (numbers[middle - 1] + numbers[middle]) / 2.0;
}
}
public static double average(long[] numbers) {
int sum = 0;
for (long l : numbers)
sum += l;
double average = 1.0d * sum / numbers.length;
return average;
}
public static long[] percentiles(long[] numbers, double... percentiles) {
Arrays.sort(numbers, 0, numbers.length);
long[] values = new long[percentiles.length];
for (int i = 0; i < percentiles.length; i++) {
int index = (int) (percentiles[i] * numbers.length);
values[i] = numbers[index];
}
return values;
}Solution
Validate your inputs
The
Note that the primary purpose of asset statements is documentation. Although a failed assert will crash the program, but only during development, as assert statements are removed from release builds, and so don't get executed in production. If you want to validate input, use exceptions instead.
Watch out for corner cases
This statement may overflow if the two numbers are too big:
To avoid overflow, you could divide each by 2 and then sum.
Simplify
If you omit the second and third parameters of
There is already a library method to calculate average:
The
median and average methods will throw an exception if the input array is empty. Think of the preconditions and if there are safe assumptions (input will never be empty) then document it, possibly with an assert statement, for example:assert numbers.length > 0;Note that the primary purpose of asset statements is documentation. Although a failed assert will crash the program, but only during development, as assert statements are removed from release builds, and so don't get executed in production. If you want to validate input, use exceptions instead.
Watch out for corner cases
This statement may overflow if the two numbers are too big:
return (numbers[middle - 1] + numbers[middle]) / 2.0;To avoid overflow, you could divide each by 2 and then sum.
Simplify
If you omit the second and third parameters of
Arrays.sort, by default it will use 0 and the length of the array. So you can omit these parameters in all your examples.There is already a library method to calculate average:
return LongStream.of(numbers).average();Code Snippets
assert numbers.length > 0;return (numbers[middle - 1] + numbers[middle]) / 2.0;return LongStream.of(numbers).average();Context
StackExchange Code Review Q#149938, answer score: 2
Revisions (0)
No revisions yet.