SearchedItemsLinkedList.java
package org.troy.capstone.data_structures;
import java.util.List;
import java.util.Optional;
import org.troy.capstone.entities.Item;
import org.troy.capstone.interfaces.ItemRepo;
/**
* The {@code SearchedItemsLinkedList} class represents a custom linked list data structure that organizes search results into pages.
* Each node in the linked list contains a list of items corresponding to a page of search results, and the list provides methods to navigate between pages.
*/
public class SearchedItemsLinkedList{
/** The head node of the linked list. */
private ItemListNode head;
/** The current node in the linked list, representing the current page of search results. */
private ItemListNode current;
/** The number of items to display per page. */
private static final int ITEMS_PER_PAGE = 10;
/** The total number of pages in the linked list, calculated based on the total number of items and items per page. */
private int pageCount = 0;
/** Constructor for {@code SearchedItemsLinkedList}. Initializes the linked list based on a list of item IDs and an item repository.
* @pre {@code itemRepo} should contain valid item data for all item IDs in {@code itemIdList}, and {@code itemIdList} should not be null.
* @param itemRepo The item repository containing all items, used to populate the linked list nodes based on the provided item IDs.
* @param itemIdList The list of item IDs representing the search results to be organized into pages in the linked list.
*/
@SuppressWarnings("null")
public SearchedItemsLinkedList(ItemRepo itemRepo, List<String> itemIdList){
if (itemIdList.isEmpty()) {
head = null;
return;
}
ItemListNode currentNode = null;
int totalItems = itemIdList.size();
pageCount = 0;
for (int startIndex = 0; startIndex < totalItems; startIndex += ITEMS_PER_PAGE) {
pageCount++;
//Get items to a list
int endIndex = Math.min(startIndex + ITEMS_PER_PAGE, totalItems);
List<Item> pageItems
= itemIdList.subList(startIndex, endIndex).stream()
.map(itemRepo::getItem)
.map(Optional::orElseThrow)
.toList();
ItemListNode newNode = new ItemListNode(pageItems);
if (head == null) {
head = newNode;
currentNode = head;
} else {
currentNode.setNext(newNode);
newNode.setPrev(currentNode);
currentNode = newNode;
}
}
current = head;
}
/** Returns the total number of pages in the linked list.
* @return The total number of pages, calculated based on the total number of items and items per page.
*/
public int getPageCount() {
return pageCount;
}
/** Returns the list of items in the head node of the linked list.
* @return The list of items in the head node, or null if the linked list is empty.
*/
public List<Item> getHead() {
if (head == null)
return null;
return head.getItems();
}
/** Returns the list of items in the next node of the linked list.
*
* @post If there is a next node, the current node is advanced to the next node.
*
* @return The list of items in the next node, or null if there is no next node.
*/
public List<Item> getNext(){
if ( current.getNext() == null ) {
System.out.println("Already at the end of the list, cannot advance further.");
return null;
}
current = current.getNext();
System.out.println("Advanced to next page of results.");
return current.getItems();
}
/** Returns the list of items in the previous node of the linked list.
* @post If there is a previous node, the current node is moved to the previous node.
*
* @return The list of items in the previous node, or null if there is no previous node.
*/
public List<Item> getPrevious(){
if ( current.getPrev() == null ) {
System.out.println("Already at the start of the list, cannot go back further.");
return null;
}
current = current.getPrev();
System.out.println("Went back to previous page of results.");
return current.getItems();
}
/** Private inner class representing a node in the linked list. */
private static class ItemListNode{
/** The list of items corresponding to a page of search results contained in this node. */
private final List<Item> items;
/** The next node in the linked list. */
private ItemListNode next;
/** The previous node in the linked list. */
private ItemListNode prev;
/** Constructor for {@code ItemListNode}.
* @pre {@code items} should be a valid list of items corresponding to a page of search results, and should not be null.
* @param items The list of items to be contained in this node, representing a page of search results.
*/
public ItemListNode(List<Item> items) {
this.items = items;
}
/** Returns the list of items contained in this node.
* @return The list of items in this node.
*/
public List<Item> getItems() {
return items;
}
/** Returns the next node in the linked list.
* @return The next node in the linked list, or null if there is none.
*/
public ItemListNode getNext() {
return next;
}
/** Returns the previous node in the linked list.
* @return The previous node in the linked list, or null if there is none.
*/
public ItemListNode getPrev() {
return prev;
}
/** Sets the next node in the linked list.
* @pre {@code next} should be a valid {@code ItemListNode} or null.
* @param next The node to set as the next node in the linked list.
*/
public void setNext(ItemListNode next) {
this.next = next;
}
/** Sets the previous node in the linked list.
* @pre {@code prev} should be a valid {@code ItemListNode} or null.
* @param prev The node to set as the previous node in the linked list.
*/
public void setPrev(ItemListNode prev) {
this.prev = prev;
}
}
}