DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Curious about the future of data-driven systems? Join our Data Engineering roundtable and learn how to build scalable data platforms.

Data Engineering: The industry has come a long way from organizing unstructured data to adopting today's modern data pipelines. See how.

Threat Detection: Learn core practices for managing security risks and vulnerabilities in your organization — don't regret those threats!

Managing API integrations: Assess your use case and needs — plus learn patterns for the design, build, and maintenance of your integrations.

Trending

  • High-Performance Reactive REST API and Reactive DB Connection Using Java Spring Boot WebFlux R2DBC Example
  • Advanced CI/CD Pipeline Optimization Techniques Using GitHub Actions
  • How to Protect Yourself From the Inevitable GenAI Crash
  • The Modern Era of Data Orchestration: From Data Fragmentation to Collaboration

Flattening Iterator

By 
Snippets Manager user avatar
Snippets Manager
·
Feb. 14, 07 · Code Snippet
Likes (0)
Comment
Save
Tweet
Share
2.4K Views

Join the DZone community and get the full member experience.

Join For Free
A trivial utility class for iterating through a collection of objects in a 'flat' manner, descending into any collections (in this case defined as iterators, iterables or arrays, rather than elements of the Collection interface ) it finds and iterating through their elements. This preserves order, so {a, b, {c, d, {e}}} will be iterated through as a, b, c, d, e.

It's not very complicated, but the implementation amused me so I thought I'd share it.


package playground.library.functional.iterator;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;

/**
 * An iterator that 'flattens out' collections, iterators, arrays, etc. 
 *
 * That is it will iterate out their contents in order, descending into any 
 * iterators, iterables or arrays provided to it.
 *
 * An example (not valid Java for brevity - some type declarations are ommitted):
 *
 * new FlattingIterator({1, 2, 3}, {{1, 2}, {3}}, new ArrayList({1, 2, 3}))
 *
 * Will iterate through the sequence 1, 2, 3, 1, 2, 3, 1, 2, 3.
 *
 * Note that this implements a non-generic version of the Iterator interface so
 * may be cast appropriately - it's very hard to give this class an appropriate 
 * generic type.
 *
 * @author david
 */
public class FlatteningIterator implements Iterator
{
    // Marker object. This is never exposed outside this class, so can be guaranteed
    // to be != anything else. We use it to indicate an absense of any other object.
    private final Object blank = new Object();
    
    /* This stack stores all the iterators found so far. The head of the stack is
     * the iterator which we are currently progressing through */
    private final Stack> iterators = new Stack>();
    
    // Storage field for the next element to be returned. blank when the next element
    // is currently unknown.
    private Object next = blank;
        
    public FlatteningIterator(Object... objects){
        this.iterators.push(Arrays.asList(objects).iterator());}
    
    public void remove(){
        /* Not implemented */}
    
    private void moveToNext(){
        if ((next == blank) && !this.iterators.empty() ) {
            if (!iterators.peek().hasNext()){
                iterators.pop();
                moveToNext();}
                else{
                    final Object next = iterators.peek().next();
                    if (next instanceof Iterator){
                      iterators.push((Iterator)next);
                      moveToNext();}
                    else if (next instanceof Iterable){
                       iterators.push(((Iterable)next).iterator());
                       moveToNext();}
                    else if (next instanceof Array){
                        iterators.push(Arrays.asList((Array)next).iterator());
                        moveToNext();}
                    else this.next = next;}}}
    
    /**
     * Returns the next element in our iteration, throwing a NoSuchElementException
     * if none is found. 
     */
    public Object next() {
        moveToNext();
        
        if (this.next == blank) throw new NoSuchElementException();
        else{
            Object next = this.next;
            this.next = blank;
            return next;
        }}
    
    /**
     * Returns if there are any objects left to iterate over. This method 
     * can change the internal state of the object when it is called, but repeated
     * calls to it will not have any additional side effects.
     */
    public boolean hasNext(){
        moveToNext();
        return (this.next != blank);}    
}

Opinions expressed by DZone contributors are their own.

Partner Resources


Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: