diff --git a/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java b/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java
new file mode 100644
index 000000000000..05e70f635055
--- /dev/null
+++ b/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java
@@ -0,0 +1,55 @@
+package com.thealgorithms.randomized;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Reservoir Sampling Algorithm
+ *
+ * Use Case:
+ * - Efficient for selecting k random items from a stream of unknown size
+ * - Used in streaming systems, big data, and memory-limited environments
+ *
+ * Time Complexity: O(n)
+ * Space Complexity: O(k)
+ *
+ * @author Michael Alexander Montoya (@cureprotocols)
+ * @see Reservoir Sampling - Wikipedia
+ */
+public final class ReservoirSampling {
+
+ // Prevent instantiation of utility class
+ private ReservoirSampling() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ /**
+ * Selects k random elements from a stream using reservoir sampling.
+ *
+ * @param stream The input stream as an array of integers.
+ * @param sampleSize The number of elements to sample.
+ * @return A list containing k randomly selected elements.
+ */
+ public static List sample(int[] stream, int sampleSize) {
+ if (sampleSize > stream.length) {
+ throw new IllegalArgumentException("Sample size cannot exceed stream size.");
+ }
+
+ List reservoir = new ArrayList<>(sampleSize);
+ Random rand = new Random();
+
+ for (int i = 0; i < stream.length; i++) {
+ if (i < sampleSize) {
+ reservoir.add(stream[i]);
+ } else {
+ int j = rand.nextInt(i + 1);
+ if (j < sampleSize) {
+ reservoir.set(j, stream[i]);
+ }
+ }
+ }
+
+ return reservoir;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java b/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java
new file mode 100644
index 000000000000..0c6061fcde2a
--- /dev/null
+++ b/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java
@@ -0,0 +1,45 @@
+package com.thealgorithms.randomized;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+public class ReservoirSamplingTest {
+
+ @Test
+ public void testSampleSizeEqualsStreamLength() {
+ int[] stream = {1, 2, 3, 4, 5};
+ int sampleSize = 5;
+
+ List result = ReservoirSampling.sample(stream, sampleSize);
+
+ assertEquals(sampleSize, result.size());
+ assertTrue(Arrays.stream(stream).allMatch(result::contains));
+ }
+
+ @Test
+ public void testSampleSizeLessThanStreamLength() {
+ int[] stream = {10, 20, 30, 40, 50, 60};
+ int sampleSize = 3;
+
+ List result = ReservoirSampling.sample(stream, sampleSize);
+
+ assertEquals(sampleSize, result.size());
+ for (int value : result) {
+ assertTrue(Arrays.stream(stream).anyMatch(x -> x == value));
+ }
+ }
+
+ @Test
+ public void testSampleSizeGreaterThanStreamLengthThrowsException() {
+ int[] stream = {1, 2, 3};
+
+ Exception exception = assertThrows(IllegalArgumentException.class, () -> ReservoirSampling.sample(stream, 5));
+
+ assertEquals("Sample size cannot exceed stream size.", exception.getMessage());
+ }
+}