package unit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * storm-0001: Fields constructor — ArrayList.contains() O(n²) vs HashMap.containsKey() O(n). * * Standalone unit test — no JUnit required. * Compile: javac -d . StormFieldsDedupTest.java * Run: java unit.StormFieldsDedupTest */ public class StormFieldsDedupTest { static long slowOps; static long fastOps; /** * Slow: mirrors original Fields(List) — uses ArrayList.contains() for dup check. * O(n²) because contains() scans the growing list for each of n fields. */ static List slowFields(List input) { slowOps = 0; List fields = new ArrayList<>(input.size()); for (String field : input) { slowOps++; // outer iteration for (String existing : fields) { // ArrayList.contains() scan slowOps++; if (existing.equals(field)) { throw new IllegalArgumentException("duplicate field '" + field + "'"); } } fields.add(field); } return fields; } /** * Fast: patched version — checks index HashMap (O(1)) and populates it inline. * O(n) total. */ static List fastFields(List input) { fastOps = 0; List fields = new ArrayList<>(input.size()); Map index = new HashMap<>(); for (String field : input) { fastOps++; // outer iteration fastOps++; // HashMap.containsKey() — O(1) if (index.containsKey(field)) { throw new IllegalArgumentException("duplicate field '" + field + "'"); } fields.add(field); index.put(field, fields.size() - 1); } return fields; } static void run(int n, int expectedNx) { List input = new ArrayList<>(); for (int i = 0; i < n; i++) input.add("field_" + i); List slowResult = slowFields(input); List fastResult = fastFields(input); boolean resultsMatch = slowResult.equals(fastResult); boolean quadraticWorse = slowOps > fastOps * expectedNx; System.out.printf("n=%-4d slow=%6d fast=%4d ratio=%5.1fx match=%b PASS=%b%n", n, slowOps, fastOps, (double) slowOps / fastOps, resultsMatch, resultsMatch && quadraticWorse); if (!resultsMatch || !quadraticWorse) { throw new AssertionError( "FAIL n=" + n + " resultsMatch=" + resultsMatch + " slowOps=" + slowOps + " fastOps=" + fastOps + " needed ratio>" + expectedNx); } } public static void main(String[] args) { System.out.println("=== storm-0001: Fields constructor O(n^2) vs O(n) ==="); run(100, 10); run(500, 30); run(1000, 60); System.out.println("3/3 PASS"); } }