Repository: TheAlgorithms/Java
Pull request #4339 (2023-08-30 05:49:31)

Added different types of Mean
Changes for feature request #4338 

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x]  This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x]  All functions and variable names follow Java naming conventions.
- [x]  All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.

punit324: @vil02 I consider all your suggestion and will incorporate them.
Except one, where you are suggesting to use some iterable for input type other that `double[]`.
As `Mean` can only be computed for numbers, `double` can hold all the numbers including `intergers` and `floats`. 
If you want I can change it to `Array<Double>` class. 
siriak: @vil02 please review again
punit324: @vil02 
I've incorporated all your suggestions.
Please review again.

Patch:
diff --git a/pom.xml b/pom.xml
index 0347ccdb..86922e1f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.thealgorithms</groupId>
     <artifactId>Java</artifactId>
@@ -52,6 +52,11 @@
             <artifactId>commons-lang3</artifactId>
             <version>3.12.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.4</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/src/main/java/com/thealgorithms/maths/Means.java b/src/main/java/com/thealgorithms/maths/Means.java
new file mode 100644
index 00000000..dccc820b
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/Means.java
@@ -0,0 +1,54 @@
+package com.thealgorithms.maths;
+
+import java.util.stream.StreamSupport;
+import org.apache.commons.collections4.IterableUtils;
+
+/**
+ * https://en.wikipedia.org/wiki/Mean
+ * <p>
+ * by: Punit Patel
+ */
+public final class Means {
+
+    private Means() {
+    }
+
+    /**
+     * @brief computes the [Arithmetic Mean](https://en.wikipedia.org/wiki/Arithmetic_mean) of the input
+     * @param numbers the input numbers
+     * @throws IllegalArgumentException empty input
+     * @return the arithmetic mean of the input numbers
+     */
+    public static Double arithmetic(final Iterable<Double> numbers) {
+        checkIfNotEmpty(numbers);
+        return StreamSupport.stream(numbers.spliterator(), false).reduce((x, y) -> x + y).get() / IterableUtils.size(numbers);
+    }
+
+    /**
+     * @brief computes the [Geometric Mean](https://en.wikipedia.org/wiki/Geometric_mean) of the input
+     * @param numbers the input numbers
+     * @throws IllegalArgumentException empty input
+     * @return the geometric mean of the input numbers
+     */
+    public static Double geometric(final Iterable<Double> numbers) {
+        checkIfNotEmpty(numbers);
+        return Math.pow(StreamSupport.stream(numbers.spliterator(), false).reduce((x, y) -> x * y).get(), 1d / IterableUtils.size(numbers));
+    }
+
+    /**
+     * @brief computes the [Harmonic Mean](https://en.wikipedia.org/wiki/Harmonic_mean) of the input
+     * @param numbers the input numbers
+     * @throws IllegalArgumentException empty input
+     * @return the harmonic mean of the input numbers
+     */
+    public static Double harmonic(final Iterable<Double> numbers) {
+        checkIfNotEmpty(numbers);
+        return IterableUtils.size(numbers) / StreamSupport.stream(numbers.spliterator(), false).reduce(0d, (x, y) -> x + 1d / y);
+    }
+
+    private static void checkIfNotEmpty(final Iterable<Double> numbers) {
+        if (!numbers.iterator().hasNext()) {
+            throw new IllegalArgumentException("Emtpy list given for Mean computation.");
+        }
+    }
+}


Test patch:
diff --git a/src/test/java/com/thealgorithms/maths/MeansTest.java b/src/test/java/com/thealgorithms/maths/MeansTest.java
new file mode 100644
index 00000000..fa17cea6
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/MeansTest.java
@@ -0,0 +1,71 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+import org.assertj.core.util.Lists;
+import org.assertj.core.util.Sets;
+import org.junit.jupiter.api.Test;
+
+class MeansTest {
+
+    @Test
+    void arithmeticMeanZeroNumbers() throws IllegalArgumentException {
+        List<Double> numbers = new ArrayList<>();
+        assertThrows(IllegalArgumentException.class, () -> Means.arithmetic(numbers));
+    }
+
+    @Test
+    void geometricMeanZeroNumbers() throws IllegalArgumentException {
+        List<Double> numbers = new ArrayList<>();
+        assertThrows(IllegalArgumentException.class, () -> Means.geometric(numbers));
+    }
+
+    @Test
+    void harmonicMeanZeroNumbers() throws IllegalArgumentException {
+        List<Double> numbers = new ArrayList<>();
+        assertThrows(IllegalArgumentException.class, () -> Means.harmonic(numbers));
+    }
+
+    @Test
+    void arithmeticMeanSingleNumber() {
+        List<Double> numbers = Lists.newArrayList(2.5);
+        assertEquals(2.5, Means.arithmetic(numbers));
+    }
+
+    @Test
+    void geometricMeanSingleNumber() {
+        Set<Double> numbers = Sets.newHashSet(Lists.newArrayList(2.5));
+        assertEquals(2.5, Means.geometric(numbers));
+    }
+
+    @Test
+    void harmonicMeanSingleNumber() {
+        LinkedHashSet<Double> numbers = Sets.newLinkedHashSet(2.5);
+        assertEquals(2.5, Means.harmonic(numbers));
+    }
+
+    @Test
+    void arithmeticMeanMultipleNumbers() {
+        Set<Double> numbers = Sets.newTreeSet(1d, 2.5, 83.3, 25.9999, 46.0001, 74.7, 74.5);
+        assertEquals(44, Means.arithmetic(numbers));
+    }
+
+    @Test
+    void geometricMeanMultipleNumbers() {
+        LinkedList<Double> numbers = new LinkedList<>() {};
+        numbers.addAll(Lists.newArrayList(1d, 2d, 3d, 4d, 5d, 6d, 1.25));
+        assertEquals(2.6426195539300585, Means.geometric(numbers));
+    }
+
+    @Test
+    void harmonicMeanMultipleNumbers() {
+        Vector<Double> numbers = new Vector<>(Lists.newArrayList(1d, 2.5, 83.3, 25.9999, 46.0001, 74.7, 74.5));
+        assertEquals(4.6697322801074135, Means.harmonic(numbers));
+    }
+}