MaterialTypeIterator.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 type.
* Only returns materials of the specified type.
*
* @author Navid Mohaghegh
* @version 3.0
* @since 2024-09-15
*/
public class MaterialTypeIterator implements MaterialIterator {
private final List<Material> materials;
private final Material.MaterialType targetType;
private int currentIndex;
private final int totalCount;
/**
* Creates a new material type iterator.
*
* @param materials the list of materials to iterate over
* @param targetType the type of materials to filter for
*/
public MaterialTypeIterator(List<Material> materials, Material.MaterialType targetType) {
this.materials = new ArrayList<>(materials);
this.targetType = targetType;
this.currentIndex = 0;
this.totalCount = (int) materials.stream()
.filter(m -> m.getType() == targetType)
.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 target type this iterator filters for.
*
* @return the target material type
*/
public Material.MaterialType getTargetType() {
return targetType;
}
/**
* Advances to the next material of the target type.
*/
private void advanceToNext() {
while (currentIndex < materials.size() &&
materials.get(currentIndex).getType() != targetType) {
currentIndex++;
}
}
@Override
public String toString() {
return String.format("MaterialTypeIterator[Type=%s, Position=%d/%d]",
targetType, getCurrentPosition(), getTotalCount());
}
}