PriceRangeIterator.java
package com.university.bookstore.iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import com.university.bookstore.model.Material;
/**
* Iterator that filters materials by price range.
* Only returns materials within the specified price range.
*
* @author Navid Mohaghegh
* @version 3.0
* @since 2024-09-15
*/
public class PriceRangeIterator implements MaterialIterator {
private final List<Material> materials;
private final double minPrice;
private final double maxPrice;
private int currentIndex;
private final int totalCount;
/**
* Creates a new price range iterator.
*
* @param materials the list of materials to iterate over
* @param minPrice the minimum price (inclusive)
* @param maxPrice the maximum price (inclusive)
* @throws IllegalArgumentException if price range is invalid
*/
public PriceRangeIterator(List<Material> materials, double minPrice, double maxPrice) {
if (minPrice < 0 || maxPrice < 0 || minPrice > maxPrice) {
throw new IllegalArgumentException("Invalid price range: " + minPrice + " to " + maxPrice);
}
this.materials = new ArrayList<>(materials);
this.minPrice = minPrice;
this.maxPrice = maxPrice;
this.currentIndex = 0;
this.totalCount = (int) materials.stream()
.filter(m -> m.getPrice() >= minPrice && m.getPrice() <= maxPrice)
.count();
advanceToNext();
}
@Override
public boolean hasNext() {
return currentIndex < materials.size();
}
@Override
public Material next() {
if (!hasNext()) {
throw new NoSuchElementException("No more elements");
}
Material current = materials.get(currentIndex);
currentIndex++;
advanceToNext();
return current;
}
@Override
public void reset() {
currentIndex = 0;
advanceToNext();
}
@Override
public int getCurrentPosition() {
return currentIndex;
}
@Override
public int getTotalCount() {
return totalCount;
}
@Override
public int getRemainingCount() {
return totalCount - getCurrentPosition();
}
@Override
public boolean isAtBeginning() {
return currentIndex == 0;
}
@Override
public boolean isAtEnd() {
return currentIndex >= materials.size();
}
/**
* Gets the minimum price.
*
* @return the minimum price
*/
public double getMinPrice() {
return minPrice;
}
/**
* Gets the maximum price.
*
* @return the maximum price
*/
public double getMaxPrice() {
return maxPrice;
}
/**
* Gets the price range.
*
* @return the price range
*/
public double getPriceRange() {
return maxPrice - minPrice;
}
/**
* Advances to the next material within the price range.
*/
private void advanceToNext() {
while (currentIndex < materials.size()) {
Material material = materials.get(currentIndex);
if (material.getPrice() >= minPrice && material.getPrice() <= maxPrice) {
break;
}
currentIndex++;
}
}
@Override
public String toString() {
return String.format("PriceRangeIterator[Range=$%.2f-$%.2f, Position=%d/%d]",
minPrice, maxPrice, getCurrentPosition(), getTotalCount());
}
}