javaintermediate
Custom Iterator and Iterable
Implement custom iterators and iterables for specialized data traversal and lazy sequence generation.
javaPress ⌘/Ctrl + Shift + C to copy
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class CustomIterators {
// Range iterator (lazy)
static class Range implements Iterable<Integer> {
private final int start, end, step;
Range(int start, int end, int step) {
this.start = start;
this.end = end;
this.step = step;
}
static Range of(int start, int end) { return new Range(start, end, 1); }
static Range of(int start, int end, int step) { return new Range(start, end, step); }
@Override
public Iterator<Integer> iterator() {
return new Iterator<>() {
private int current = start;
public boolean hasNext() { return current < end; }
public Integer next() {
if (!hasNext()) throw new NoSuchElementException();
int val = current;
current += step;
return val;
}
};
}
// Support streams
public Stream<Integer> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
// Fibonacci iterator (infinite)
static class Fibonacci implements Iterable<Long> {
@Override
public Iterator<Long> iterator() {
return new Iterator<>() {
private long a = 0, b = 1;
public boolean hasNext() { return true; }
public Long next() {
long result = a;
long temp = a + b;
a = b;
b = temp;
return result;
}
};
}
public Stream<Long> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
// Window/sliding iterator
static <T> Iterator<List<T>> sliding(List<T> list, int windowSize) {
return new Iterator<>() {
private int pos = 0;
public boolean hasNext() { return pos + windowSize <= list.size(); }
public List<T> next() {
if (!hasNext()) throw new NoSuchElementException();
List<T> window = list.subList(pos, pos + windowSize);
pos++;
return window;
}
};
}
// Generate from function
static <T> Iterable<T> generate(T seed, UnaryOperator<T> next, Predicate<T> hasNext) {
return () -> new Iterator<>() {
private T current = seed;
public boolean hasNext() { return hasNext.test(current); }
public T next() {
T val = current;
current = next.apply(current);
return val;
}
};
}
public static void main(String[] args) {
// Range
for (int i : Range.of(0, 10, 2)) {
System.out.print(i + " "); // 0 2 4 6 8
}
System.out.println();
// Fibonacci
new Fibonacci().stream()
.limit(10)
.forEach(n -> System.out.print(n + " ")); // 0 1 1 2 3 5 8 13 21 34
System.out.println();
// Sliding window
var list = List.of(1, 2, 3, 4, 5);
sliding(list, 3).forEachRemaining(System.out::println);
// Powers of 2
for (long n : generate(1L, x -> x * 2, x -> x < 1000)) {
System.out.print(n + " "); // 1 2 4 8 ... 512
}
}
}Use Cases
- Lazy sequence generation for large datasets
- Sliding window algorithms
- Custom traversal patterns for domain objects
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
javabeginner
HashMap Operations and Patterns
Essential HashMap operations: put, get, merge, compute, getOrDefault, and iteration patterns.
Best for: Counting word frequencies in text
#java#collections
javabeginner
Java Streams — Filter, Map, Collect
Process collections with Java Streams: filter, map, flatMap, reduce, and collect to lists or maps.
Best for: Transforming and filtering collections
#java#streams
javaadvanced
Concurrent Collections — Thread-Safe Maps
Use ConcurrentHashMap, CopyOnWriteArrayList, and BlockingQueue for thread-safe data structures.
Best for: Thread-safe caching in multi-threaded applications
#java#concurrency
javaadvanced
Java Generics — Bounded Types and Wildcards
Master Java generics: bounded types, wildcards, generic methods, and type-safe collection utilities.
Best for: Type-safe generic utility methods and classes
#java#generics