Collections
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
HashSet (Unique Item)
```java import java.util.HashSet; import java.util.Set;
Set
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
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
// 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
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
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
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>