diff --git a/src/main/java/com/thealgorithms/datastructures/bags/Bag.java b/src/main/java/com/thealgorithms/datastructures/bags/Bag.java index ff5c832baeaf..1bb143fabda1 100644 --- a/src/main/java/com/thealgorithms/datastructures/bags/Bag.java +++ b/src/main/java/com/thealgorithms/datastructures/bags/Bag.java @@ -4,23 +4,23 @@ import java.util.NoSuchElementException; /** - * Collection which does not allow removing elements (only collect and iterate) + * A collection that allows adding and iterating over elements but does not support element removal. * - * @param - the generic type of an element in this bag + * @param the type of elements in this bag */ -public class Bag implements Iterable { +public class Bag implements Iterable { - private Node firstElement; // first element of the bag - private int size; // size of bag + private Node firstElement; // First element in the bag + private int size; // Number of elements in the bag - private static final class Node { - - private Element content; - private Node nextElement; + // Node class representing each element in the bag + private static final class Node { + private E content; + private Node nextElement; } /** - * Create an empty bag + * Constructs an empty bag. */ public Bag() { firstElement = null; @@ -28,13 +28,17 @@ public Bag() { } /** - * @return true if this bag is empty, false otherwise + * Checks if the bag is empty. + * + * @return true if the bag is empty, false otherwise */ public boolean isEmpty() { - return firstElement == null; + return size == 0; } /** + * Returns the number of elements in the bag. + * * @return the number of elements */ public int size() { @@ -42,24 +46,26 @@ public int size() { } /** - * @param element - the element to add + * Adds an element to the bag. + * + * @param element the element to add */ - public void add(Element element) { - Node oldfirst = firstElement; - firstElement = new Node<>(); - firstElement.content = element; - firstElement.nextElement = oldfirst; + public void add(E element) { + Node newNode = new Node<>(); + newNode.content = element; + newNode.nextElement = firstElement; + firstElement = newNode; size++; } /** - * Checks if the bag contains a specific element + * Checks if the bag contains a specific element. * - * @param element which you want to look for - * @return true if bag contains element, otherwise false + * @param element the element to check for + * @return true if the bag contains the element, false otherwise */ - public boolean contains(Element element) { - for (Element value : this) { + public boolean contains(E element) { + for (E value : this) { if (value.equals(element)) { return true; } @@ -68,61 +74,37 @@ public boolean contains(Element element) { } /** - * @return an iterator that iterates over the elements in this bag in - * arbitrary order + * Returns an iterator over the elements in this bag. + * + * @return an iterator that iterates over the elements in the bag */ - public Iterator iterator() { + @Override + public Iterator iterator() { return new ListIterator<>(firstElement); } - @SuppressWarnings("hiding") - private class ListIterator implements Iterator { + // Private class for iterating over elements + private static class ListIterator implements Iterator { - private Node currentElement; + private Node currentElement; - ListIterator(Node firstElement) { - currentElement = firstElement; + ListIterator(Node firstElement) { + this.currentElement = firstElement; } + @Override public boolean hasNext() { return currentElement != null; } - /** - * remove is not allowed in a bag - */ @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - public Element next() { + public E next() { if (!hasNext()) { throw new NoSuchElementException(); } - Element element = currentElement.content; + E element = currentElement.content; currentElement = currentElement.nextElement; return element; } } - - /** - * main-method for testing - */ - public static void main(String[] args) { - Bag bag = new Bag<>(); - - bag.add("1"); - bag.add("1"); - bag.add("2"); - - System.out.println("size of bag = " + bag.size()); - for (String s : bag) { - System.out.println(s); - } - - System.out.println(bag.contains(null)); - System.out.println(bag.contains("1")); - System.out.println(bag.contains("3")); - } } diff --git a/src/test/java/com/thealgorithms/datastructures/bag/BagTest.java b/src/test/java/com/thealgorithms/datastructures/bag/BagTest.java new file mode 100644 index 000000000000..c0fe107bfba5 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/bag/BagTest.java @@ -0,0 +1,111 @@ +package com.thealgorithms.datastructures.bag; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.datastructures.bags.Bag; +import java.util.Iterator; +import org.junit.jupiter.api.Test; + +class BagTest { + + @Test + void testBagOperations() { + Bag bag = new Bag<>(); + assertTrue(bag.isEmpty(), "Bag should be empty initially"); + assertEquals(0, bag.size(), "Bag size should be 0 initially"); + + bag.add("item1"); + bag.add("item2"); + bag.add("item1"); // adding duplicate item + + assertFalse(bag.isEmpty(), "Bag should not be empty after adding elements"); + assertEquals(3, bag.size(), "Bag size should be 3 after adding 3 elements"); + + assertTrue(bag.contains("item1"), "Bag should contain 'item1'"); + assertTrue(bag.contains("item2"), "Bag should contain 'item2'"); + assertFalse(bag.contains("item3"), "Bag should not contain 'item3'"); + assertFalse(bag.contains(null), "Bag should not contain null"); + + // Test iteration + int count = 0; + for (String item : bag) { + assertTrue(item.equals("item1") || item.equals("item2"), "Item should be either 'item1' or 'item2'"); + count++; + } + assertEquals(3, count, "Iterator should traverse all 3 items"); + } + + @Test + void testBagInitialization() { + Bag bag = new Bag<>(); + assertTrue(bag.isEmpty(), "Bag should be empty initially"); + assertEquals(0, bag.size(), "Bag size should be 0 initially"); + } + + @Test + void testAddElements() { + Bag bag = new Bag<>(); + bag.add("item1"); + bag.add("item2"); + bag.add("item1"); // Adding duplicate item + + assertFalse(bag.isEmpty(), "Bag should not be empty after adding elements"); + assertEquals(3, bag.size(), "Bag size should be 3 after adding 3 elements"); + } + + @Test + void testContainsMethod() { + Bag bag = new Bag<>(); + bag.add("item1"); + bag.add("item2"); + + assertTrue(bag.contains("item1"), "Bag should contain 'item1'"); + assertTrue(bag.contains("item2"), "Bag should contain 'item2'"); + assertFalse(bag.contains("item3"), "Bag should not contain 'item3'"); + assertFalse(bag.contains(null), "Bag should not contain null"); + } + + @Test + void testContainsAfterRemoveOperation() { + Bag bag = new Bag<>(); + bag.add("item1"); + bag.add("item2"); + assertTrue(bag.contains("item1"), "Bag should contain 'item1' before removal"); + assertTrue(bag.contains("item2"), "Bag should contain 'item2' before removal"); + } + + @Test + void testIterator() { + Bag bag = new Bag<>(); + bag.add("item1"); + bag.add("item2"); + bag.add("item3"); + + int count = 0; + for (String item : bag) { + assertTrue(item.equals("item1") || item.equals("item2") || item.equals("item3"), "Item should be one of 'item1', 'item2', or 'item3'"); + count++; + } + assertEquals(3, count, "Iterator should traverse all 3 items"); + } + + @Test + void testIteratorEmptyBag() { + Bag bag = new Bag<>(); + int count = 0; + for (String ignored : bag) { + org.junit.jupiter.api.Assertions.fail("Iterator should not return any items for an empty bag"); + } + assertEquals(0, count, "Iterator should not traverse any items in an empty bag"); + } + + @Test + void testRemoveMethodThrowsException() { + Bag bag = new Bag<>(); + bag.add("item1"); + Iterator iterator = bag.iterator(); + org.junit.jupiter.api.Assertions.assertThrows(UnsupportedOperationException.class, iterator::remove, "Remove operation should throw UnsupportedOperationException"); + } +}