Collectibles

Learning Objectives

  • Understand how to represent data using Java classes
  • Apply ArrayLists, HashMaps, and loops to manage collections
  • Practice object-oriented programming: constructors, encapsulation, and methods
  • Build a basic text-based inventory system for collectibles

📦 Collectibles in Java

📘 Introduction

In Computer Science, collections refer to groups of related data items stored in a structure that allows efficient access, organization, and manipulation. Collections are foundational to software development and are used in everything from games and databases to search engines and machine learning.

🎯 Learning Objectives

  • Represent data using Java classes
  • Apply ArrayList, HashMap, and loops to manage collections
  • Practice object-oriented programming: constructors, encapsulation, and methods
  • Build a basic text-based inventory system for collectibles

🗃️ What is a Collection?

A collection is a data structure that holds multiple elements. Collections offer methods to add, remove, search, and iterate over elements.

Common Collection Types

| Type | Description | |————–|————-| | List | Ordered, allows duplicates (e.g., ArrayList) | | Set | Unordered, no duplicates (e.g., HashSet) | | Map | Key-value pairs for fast lookups (e.g., HashMap) | | Stack | LIFO access pattern (Last-In, First-Out) | | Queue | FIFO access pattern (First-In, First-Out) |


💡 Why Use Collections?

  • Organize data logically (e.g., user profiles, game items)
  • Perform batch operations (e.g., filter, sort, search)
  • Reuse algorithms across data types

📚 Java Collection Examples

ArrayList (Ordered List)

```java import java.util.ArrayList; List fruits = new ArrayList<>(); fruits.add("apple"); fruits.add("banana");

HashSet (Unique Item)

```java import java.util.HashSet; import java.util.Set;

Set uniqueTags = new HashSet<>(); uniqueTags.add("AI"); uniqueTags.add("Python"); uniqueTags.add("Data"); uniqueTags.add("Python"); // No effect, already present

3. Dictionary (HashMap)

•	Maps keys to values.
•	Fast retrieval by key.
•	Useful for objects, configurations, or lookup tables. ```java

import java.util.HashMap; import java.util.Map;

Map<String, Object> userProfile = new HashMap<>(); userProfile.put(“name”, “Alice”); userProfile.put(“score”, 1200); userProfile.put(“level”, 5);

4. Stack

•	LIFO: Last In, First Out.
•	Used in undo systems, expression parsing, function calls. ```java import java.util.Stack; Stack<String> stack = new Stack<>(); stack.push("action1"); String lastAction = stack.pop();

5. Queue

•	FIFO: First In, First Out.
•	Used in task scheduling, print queues, or event handling. ```java

import java.util.LinkedList; Queue queue = new LinkedList<>(); queue.add("task1"); queue.add("task2"); queue.add("task3"); queue.poll(); // Removes "task1"

Part 1: Define a Collectible Class

```Java // This class represents a collectible item, like a card, toy, or in-game item public class Collectible {

// Fields (also called instance variables) that store information about each collectible
private String name;   // The name of the collectible (e.g., "Dragon Blade")
private String type;   // The category or type (e.g., "Weapon", "Fire", "Water")
private int rarity;    // An integer representing rarity level (1 = Common, 5 = Legendary)

// Constructor: This method is called when a new Collectible object is created.
// It sets the initial values for name, type, and rarity.
public Collectible(String name, String type, int rarity) {
    this.name = name;
    this.type = type;
    this.rarity = rarity;
}

// Getter method to return the name of the collectible
public String getName() { 
    return name; 
}

// Getter method to return the type/category of the collectible
public String getType() { 
    return type; 
}

// Getter method to return the rarity level
public int getRarity() { 
    return rarity; 
}

// This method provides a readable string version of the object.
// It overrides the default toString() method so we can print something like:
// "Phoenix Flame [Fire] (Rarity: 5)"
public String toString() {
    return name + " [" + type + "] (Rarity: " + rarity + ")";
} }

Key components:

  • Encapsulation: Fields are marked private to prevent direct modification from outside the class. Access is controlled using getter methods.
  • Constructor: Makes it easy to create new Collectible objects with specific values. Custom toString(): Helps print the object in a human-readable way.
  • Use Case: This class could be used in a collection (like a List or Set) to build and manage a collection of unique or rare items.

Part 2: Create an Inventory Class

```Java import java.util.ArrayList; // Import the ArrayList class from the Java Collections Framework

// This class represents an inventory that stores a collection of Collectible items public class Inventory { // Field: a dynamic list to store Collectible objects private ArrayList items;

// Constructor: initializes the ArrayList when an Inventory object is created
public Inventory() {
    items = new ArrayList<>();
}

// Adds a new Collectible item to the inventory
public void addItem(Collectible c) {
    items.add(c); // Uses ArrayList's add() method
}

// Displays all Collectibles in the inventory
public void showInventory() {
    for (Collectible c : items) {
        System.out.println(c); // Each Collectible's toString() method is called here
    }
}

// Counts how many items in the inventory match a given type (case-insensitive)
public int countByType(String type) {
    int count = 0;
    for (Collectible c : items) {
        if (c.getType().equalsIgnoreCase(type)) {
            count++;
        }
    }
    return count; // Returns the total number of matching items
} }

Key components:

  • ArrayList: A resizable list that holds all the Collectible objects (items field).
  • Encapsulation: Inventory hides the items list and provides methods to work with it.
  • Loops and Accessors: for-each loop is used to iterate through the list using getter methods.
  • Case-insensitive comparison: .equalsIgnoreCase() allows counting items regardless of text case.
  • Object-Oriented Design: The class interacts with another class (Collectible), modeling real-world systems.

Part 3: Main Program Logic

```Java public class Main { public static void main(String[] args) { // Create a new Inventory instance Inventory myInventory = new Inventory();

    // Create some Collectible objects with different types and rarities
    Collectible card1 = new Collectible("Phoenix Flame", "Fire", 5);
    Collectible card2 = new Collectible("Aqua Sprite", "Water", 3);
    Collectible card3 = new Collectible("Blazing Ember", "Fire", 2);

    // Add each Collectible to the inventory
    myInventory.addItem(card1);
    myInventory.addItem(card2);
    myInventory.addItem(card3);

    // Display all items currently in the inventory
    myInventory.showInventory();

    // Count and display how many items are of the "Fire" type
    System.out.println("Number of Fire-type items: " + myInventory.countByType("Fire"));
} }

// Runs the main method to execute the program in a notebook or REPL-style environment Main.main(null);


Phoenix Flame [Fire] (Rarity: 5)</br>
Aqua Sprite [Water] (Rarity: 3)</br>
Blazing Ember [Fire] (Rarity: 2)</br>
Number of Fire-type items: 2</br>

LIFO INVENTORY CLASS ```Java import java.util.Stack;

public class LifoInventory { private Stack stack;

public LifoInventory() {
    stack = new Stack<>();
}

public void addItem(Collectible c) {
    stack.push(c);
}

public Collectible removeItem() {
    if (!stack.isEmpty()) {
        return stack.pop();
    }
    return null;
}

public void showInventory() {
    for (Collectible c : stack) {
        System.out.println(c);
    }
} }

FIFO INVENTORY CLASS ```Java import java.util.LinkedList; import java.util.Queue;

public class FifoInventory { private Queue queue;

public FifoInventory() {
    queue = new LinkedList<>();
}

public void addItem(Collectible c) {
    queue.offer(c);
}

public Collectible removeItem() {
    return queue.poll(); // removes and returns first item
}

public void showInventory() {
    for (Collectible c : queue) {
        System.out.println(c);
    }
} }

HASHMAP INVENTORY CLASS ```Java import java.util.HashMap;

public class MapInventory { private HashMap<String, Collectible> map;

public MapInventory() {
    map = new HashMap<>();
}

public void addItem(String id, Collectible c) {
    map.put(id, c); // uses a unique ID or name as the key
}

public Collectible getItem(String id) {
    return map.get(id);
}

public void showInventory() {
    for (String key : map.keySet()) {
        System.out.println(key + " → " + map.get(key));
    }
} }

Key components:

  • Object Creation: New instances of Collectible are created with constructor values.
  • Method Calls: addItem(), showInventory(), and countByType() are called to interact with data.
  • Dynamic Storage: The ArrayList inside Inventory allows easy scaling as more items are added.
  • Encapsulation: The user of the class (in Main) doesn’t need to know how the ArrayList works internally.

Homework:

List Task: Modify your my_collection list to support bulk adding and removal of items using another list. • Create a method that takes a list of new items and adds them all to my_collection. • Create another method that removes all items in a given list from my_collection.

Dictionary Task: Modify your item_details dictionary to support value updates and rarity-based filters. • Add a method to update an item’s value by a percentage (e.g., increase all epic items by 10%). • Create a method that filters and returns all items of a given rarity.

Set Task: Add set-based tracking of items. • Use a traded_items set and a duplicate_items set. • Add a method that checks if any new item being added is already in the collection, and if so, log it in duplicate_items. • Ensure no duplicates are added to the main list.

Print Method: Create a method to display the full collection, showing: • Item name • Rarity • Value Format the output cleanly (like a table or aligned print).

Bonus Challenge: Create a method that uses a stack to simulate nested inventory folders (e.g., Weapon > Magic > Fire > Scroll). • Track your current folder path with a stack. • Allow going “deeper” and “back up” in the folder structure with push/pop. • Print the full current path using the stack.

Sample Code Snippet:

```Java Stack folderStack = new Stack<>(); folderStack.push("Weapons"); folderStack.push("Magic"); folderStack.push("Fire");

System.out.println(String.join(“ > “, folderStack)); // Output: Weapons > Magic > Fire

folderStack.pop(); // back out of Fire System.out.println(String.join(“ > “, folderStack)); // Output: Weapons > Magic


Weapons > Magic > Fire</br>
Weapons > Magic</br>