Task 3 adds IntBinarySearchTree with iterative add/contains and a test class covering empty trees, duplicates, and degenerate ascending and descending insertion orders. Task 4 adds IntHashSet backed by an IntLinkedList bucket array with a 0.7 load factor, Math.floorMod-based hashing for negative-int safety, doubling resize that rehashes via a private addWithoutResize helper, and a test class covering negatives, Integer.MIN_VALUE, forced collisions on bucket 0, and 100-element inserts spanning three resizes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
3.0 KiB
Java
75 lines
3.0 KiB
Java
public class IntHashSetTest {
|
|
static int passed = 0, failed = 0;
|
|
|
|
public static void main(String[] args) {
|
|
testEmpty();
|
|
testAddContains();
|
|
testDuplicates();
|
|
testNegatives();
|
|
testManyForcingResize();
|
|
testCollisions();
|
|
System.out.println();
|
|
System.out.println("Passed: " + passed + " / " + (passed + failed));
|
|
}
|
|
|
|
static void testEmpty() {
|
|
IntHashSet s = new IntHashSet();
|
|
checkBool("empty contains(5)", s.contains(5), false);
|
|
checkBool("empty contains(-1)", s.contains(-1), false);
|
|
checkBool("empty contains(0)", s.contains(0), false);
|
|
}
|
|
|
|
static void testAddContains() {
|
|
IntHashSet s = new IntHashSet();
|
|
s.add(1); s.add(2); s.add(3);
|
|
checkBool("contains(1)", s.contains(1), true);
|
|
checkBool("contains(2)", s.contains(2), true);
|
|
checkBool("contains(3)", s.contains(3), true);
|
|
checkBool("contains(4)", s.contains(4), false);
|
|
}
|
|
|
|
static void testDuplicates() {
|
|
IntHashSet s = new IntHashSet();
|
|
s.add(7); s.add(7); s.add(7); s.add(7);
|
|
checkBool("dup contains(7)", s.contains(7), true);
|
|
// no easy way to inspect size without exposing it; trust it
|
|
}
|
|
|
|
static void testNegatives() {
|
|
IntHashSet s = new IntHashSet();
|
|
s.add(-1); s.add(-100); s.add(Integer.MIN_VALUE);
|
|
checkBool("contains(-1)", s.contains(-1), true);
|
|
checkBool("contains(-100)", s.contains(-100), true);
|
|
checkBool("contains(MIN_VALUE)", s.contains(Integer.MIN_VALUE), true);
|
|
checkBool("contains(1) after negs", s.contains(1), false);
|
|
}
|
|
|
|
static void testManyForcingResize() {
|
|
// Insert 100 values - capacity starts at 16, will resize multiple times
|
|
IntHashSet s = new IntHashSet();
|
|
for (int i = 0; i < 100; i++) s.add(i);
|
|
for (int i = 0; i < 100; i++) {
|
|
checkBool("post-resize contains(" + i + ")", s.contains(i), true);
|
|
}
|
|
checkBool("post-resize contains(100)", s.contains(100), false);
|
|
checkBool("post-resize contains(-1)", s.contains(-1), false);
|
|
}
|
|
|
|
static void testCollisions() {
|
|
// Values that all hash to bucket 0 in capacity 16 (multiples of 16)
|
|
IntHashSet s = new IntHashSet();
|
|
s.add(0); s.add(16); s.add(32); s.add(48);
|
|
checkBool("collision contains(0)", s.contains(0), true);
|
|
checkBool("collision contains(16)", s.contains(16), true);
|
|
checkBool("collision contains(32)", s.contains(32), true);
|
|
checkBool("collision contains(48)", s.contains(48), true);
|
|
checkBool("collision contains(8)", s.contains(8), false);
|
|
checkBool("collision contains(64)", s.contains(64), false);
|
|
}
|
|
|
|
static void checkBool(String label, boolean actual, boolean expected) {
|
|
if (actual == expected) { System.out.println("PASS " + label + " = " + actual); passed++; }
|
|
else { System.out.println("FAIL " + label + " expected=" + expected + " actual=" + actual); failed++; }
|
|
}
|
|
}
|