Lesson 5
Practice Problems in Java with Queues, Deques, and Sorted Maps
Introduction to Practice Problems

Welcome to the practical segment of our Java programming journey! Today, we'll apply the knowledge from past lessons to solve two practice problems using advanced Java data structures: queues, deques, and sorted maps with custom class keys.

First Practice Problem: Implementing Queues with Deques

Consider an event-driven system, like a restaurant. Orders arrive, and they must be handled in the order they were received, following the First In, First Out (FIFO) principle. This principle makes it a perfect scenario for a queue or deque implementation in Java.

Java
1import java.util.ArrayDeque; 2import java.util.Deque; 3 4class Queue { 5 private Deque<String> buffer; 6 7 public Queue() { 8 // Initializing an empty queue 9 buffer = new ArrayDeque<>(); 10 } 11 12 // Adding (enqueueing) an item to the queue 13 public void enqueue(String val) { 14 buffer.addLast(val); 15 } 16 17 // Removing (dequeuing) an item from the queue 18 public String dequeue() { 19 if (isEmpty()) { 20 throw new IllegalStateException("Queue is empty"); 21 } 22 return buffer.removeFirst(); 23 } 24 25 // Checking if the queue is empty 26 public boolean isEmpty() { 27 return buffer.isEmpty(); 28 } 29 30 // Checking the size (number of items) in the queue 31 public int size() { 32 return buffer.size(); 33 } 34 35 public static void main(String[] args) { 36 Queue restaurantQueue = new Queue(); 37 38 restaurantQueue.enqueue("Order 1"); 39 restaurantQueue.enqueue("Order 2"); 40 41 System.out.println("Dequeued: " + restaurantQueue.dequeue()); 42 System.out.println("Dequeued: " + restaurantQueue.dequeue()); 43 } 44}

This code demonstrates the creation and operation of a Queue class, which leverages ArrayDeque to efficiently implement a queue. The Queue class includes methods to enqueue (add) an item, dequeue (remove) an item, check if the queue is empty, and return the queue's size. Enqueue operations add an item to the end of the deque (simulating the arrival of a new order), while dequeue operations remove an item from the front (simulating the serving of an order), maintaining the First In, First Out (FIFO) principle.

Analyzing the First Problem Solution

We've mimicked a real-world system by implementing a queue using Java's ArrayDeque. The enqueuing of an item adheres to the FIFO principle, similar to the action of receiving a new order at the restaurant. The dequeuing serves an order, reflecting the preparation and delivery of the order.

Second Practice Problem: Using Sorted Maps with Custom Class as a Key

For the second problem, envision a leaderboard for a video game. Players with their scores can be represented as objects of a custom class, then stored in a sorted map for easy and efficient access.

Java
1import java.util.Map; 2import java.util.TreeMap; 3 4class Player implements Comparable<Player> { 5 String name; 6 int score; 7 8 public Player(String name, int score) { 9 this.name = name; 10 this.score = score; 11 } 12 13 @Override 14 public int compareTo(Player other) { 15 if (this.score == other.score) { 16 return this.name.compareTo(other.name); 17 } 18 return Integer.compare(this.score, other.score); 19 } 20 21 @Override 22 public boolean equals(Object obj) { 23 if (this == obj) return true; 24 if (obj == null || getClass() != obj.getClass()) return false; 25 Player player = (Player) obj; 26 return score == player.score && name.equals(player.name); 27 } 28 29 @Override 30 public int hashCode() { 31 return (name + score).hashCode(); // Simple hash code generation 32 } 33 34 @Override 35 public String toString() { 36 return "(" + name + ", " + score + ")"; 37 } 38 39 public static void main(String[] args) { 40 TreeMap<Player, Integer> scores = new TreeMap<>(); 41 42 Player player1 = new Player("John", 900); 43 Player player2 = new Player("Doe", 1000); 44 45 // Adding players to the TreeMap 46 scores.put(player1, player1.score); 47 scores.put(player2, player2.score); 48 49 // Print TreeMap 50 for (Map.Entry<Player, Integer> entry : scores.entrySet()) { 51 System.out.println(entry.getKey()); // e.g., (John, 900) 52 } 53 } 54}

This code snippet introduces a Player class for representing players in a video game, incorporating the Comparable interface to allow sorting by score (primary) and name (secondary). Instances of this class are then used as keys in a TreeMap, ensuring that players are stored in a manner that is sorted first by their scores and then by their names if scores are equal. This is essential for functionalities like leaderboards, where players need to be ranked efficiently according to their performance.

Analyzing the Second Problem Solution

In our leaderboard system, we used a Player custom class with comparator methods for sorting. We stored instances of Player in a sorted map with their corresponding scores. The TreeMap allows us to access player scores in a sorted order efficiently, a common requirement in a competitive gaming system.

Lesson Summary and Practice

We've successfully employed Java's built-in data structures — queues or deques, and sorted maps — to solve real-world problems. This hands-on approach enables us to better understand these concepts. More exercises to cement your understanding are coming up next. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.