/* Copyright (c) 2011-2022 Reliancy LLC Licensed under the GNU LESSER GENERAL PUBLIC LICENSE Version 3. You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html. You may not use this file except in compliance with the License. */ package com.reliancy.rec; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; import com.reliancy.util.Arrays; /** * Iterator and Iterable for traversing {@link Slot} collections. * *
This class provides a unified interface for iterating over slots, * supporting both traditional iteration and Java 8+ Stream operations. * * Each header is iterated using local scope so you need to explictly specify an array in cases of inheritance. * *
{@code
* // For basic slots
* Slots slots = new Slots<>(header);
*
* // For fields (Field extends Slot, Entity extends Hdr)
* Slots fields = new Slots<>(entity);
*
* // Traditional iteration
* for (Slot slot : slots) {
* System.out.println(slot.getName());
* }
*
* // Stream operations
* fields.stream()
* .filter(f -> f.getName().startsWith("user_"))
* .forEach(f -> System.out.println(f.getName()));
* }
*
* The {@link #current()}, {@link #currentHeader()}, and {@link #currentIndex()} methods
* provide context about the current iteration state. Each refers to the element returned
* by the most recent call to {@link #next()} (or {@code null}/-1 before any call).
* These are useful for inspection or conditional logic during iteration.
*
* @param Returns -1 if {@link #next()} has not been called yet (i.e., before the first
* call to {@link #next()}). After each call to {@link #next()}, this value is
* incremented to reflect the index of the element that was just returned.
*
* @return the index of the last returned element, or -1 if no elements have been returned yet
*/
public int currentIndex(){
return s_current_index;
}
/**
* Removes from the underlying collection the last element returned
* by this iterator (optional operation).
*
* @throws UnsupportedOperationException if the {@code remove} operation
* is not supported by this iterator
*/
@Override
public void remove() {
throw new UnsupportedOperationException("forward only immutable view");
}
// ========================================================================
// Iterable Implementation
// ========================================================================
/**
* Returns an iterator over elements of type {@code S}.
*
* @return an Iterator
*/
@Override
public Iterator This method allows the slots to be processed using Java 8+ Stream API:
* It is allowable for this method to return a sequential stream.
*
* @return a possibly parallel Stream over the slots
*/
public Stream The slot type extending {@link Slot}
* @param implements Iterator, Iterable {
public static Slots considering(Hdr... headers){
this.headers=headers;
rewind();
return this;
}
public Slots selectBy(Selector selector){
this.selector=selector;
rewind();
return this;
}
public Slots clone(){
Slots cloned =new Slots<>(headers);
if(selector!=null){
cloned.selectBy(selector);
}
return cloned;
}
/**
* Filters fields to include only those with the specified flags set.
*
* @param flags The flag mask to match
* @return This Fields instance for method chaining
*/
public Slots including(int flags) {
selectBy(new Slots.SELECT_INCLUDING(flags));
return this;
}
/**
* Filters fields to exclude those with the specified flags set.
*
* @param flags The flag mask to exclude
* @return This Fields instance for method chaining
*/
public Slots excluding(int flags) {
selectBy(new Slots.SELECT_EXCLUDING(flags));
return this;
}
public Slots rewind(){
h_next=0;
h_slots=headers.length>0?headers[h_next].getOwnSlots():new ArrayList iterator() {
return clone();
}
// ========================================================================
// Stream Support
// ========================================================================
/**
* Returns a sequential {@code Stream} with this collection as its source.
*
* {@code
* slots.stream()
* .filter(s -> s.getName().startsWith("user_"))
* .map(Slot::getName)
* .collect(Collectors.toList());
* }
*
* @return a sequential Stream over the slots
*/
public Stream stream() {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(this, 0),
false
);
}
/**
* Returns a possibly parallel {@code Stream} with this collection as its source.
*
* parallelStream() {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(this, 0),
true
);
}
}