Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8478745
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T18:49:51+00:00 2026-06-10T18:49:51+00:00

I want them to do a custom iterator, for a wrapper set. ListIterator from(E

  • 0

I want them to do a custom iterator, for a wrapper set.

ListIterator from(E elem)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T18:49:53+00:00Added an answer on June 10, 2026 at 6:49 pm

    I’ve got a solution now that doesn’t use extension or reflection (or indeed LinkedHashMap)

    What do you think?

    package i3.util;
    
    import java.util.AbstractSet;
    import java.util.Collection;
    import java.util.ConcurrentModificationException;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.ListIterator;
    import java.util.Map;
    import java.util.NoSuchElementException;
    
    /**
     * This class is a like LinkedHashSet (insertion order) but it allows querying
     * the relative position of a element and has a ListIterator that can set and
     * insert anywhere.
     *
     * Warning: the iterator can change the order of the set by moving elements when
     * setting or adding. Elements that already exist are not ignored, but moved the
     * requested place. This changes iteration order
     *
     *
     * The iterators of this class are fail fast and will throw a
     * ConcurrentModificationException if their iterator are used with intervening
     * main class (or other iterators) mutative calls
     *
     * @author i30817 <i30817@gmail.com>
    */
    public class LinkedSet<E> extends AbstractSet<E> {
    
    //It holds the linked list
    private Map<E, Node> m = new HashMap<E, Node>();
    //head of that
    protected Node head = new Node();
    //this is copied to the map value in increments of iteratorAddStep on set.add
    //(which only adds to the end, by insertion indexing)
    private int monotonicallyIncreasing = 0;
    //iterator add step may change when doing rebuilds of the 'space' between elements
    //for the before/after functions on LinkedKeyIterator.add
    private int iteratorAddStep = 10;
    //for fail fast iterators
    private int modCount;
    
    /**
     * Start iterating from elem (inclusive)
     *
     *
     * @throws NoSuchElementException if E not part of the set
     * @param elem a element of the set
     * @return a ListIterator - doesn't support nextIndex() or previousIndex()
     */
    public ListIterator<E> from(E elem) {
        Node e = m.get(elem);
        if (e == null) {
            throw new NoSuchElementException("the given element isn't part of the set");
        }
        return new LinkedKeyIterator(e);
    }
    
    @Override
    public ListIterator<E> iterator() {
        return new LinkedKeyIterator();
    }
    
    /**
     * Returns true if the value target was added before (exclusive) limitElem
     * in insertion order.
     *
     * If target or limit are not present on the set this method returns false
     *
     * @param limitElem a E that may be a element of the set or not.
     * @return if target was added before limit (can be reset by removing and
     * re-adding the target, that changes iteration order).
     */
    public boolean containsBefore(E target, E limitElem) {
        if (isEmpty()) {
            return false;
        }
    
        Integer targetN = m.get(target).relativeLocation;
        Integer highN = m.get(limitElem).relativeLocation;
        return targetN != null && highN != null && targetN < highN;
    }
    
    /**
     * Returns true if the value target was added after (exclusive) previousElem
     * in insertion order.
     *
     * If target or previous are not present on the set this method returns
     * false
     *
     * @param previousElem a E that may be a element of the set or not.
     * @return if target was added before previous (can be reset by removing and
     * re-adding the target, that changes iteration order).
     */
    public boolean containsAfter(E target, E previousElem) {
        if (isEmpty()) {
            return false;
        }
    
        Integer targetN = m.get(target).relativeLocation;
        Integer low = m.get(previousElem).relativeLocation;
        return targetN != null && low != null && low < targetN;
    }
    
    @Override
    public boolean add(E e) {
        if (!m.containsKey(e)) {
            Node n = new Node(e, monotonicallyIncreasing);
            monotonicallyIncreasing += iteratorAddStep;
            n.addBefore(head);//insertion order
            m.put(e, n);
            return true;
        }
        return false;
    }
    
    @Override
    public int size() {
        return m.size();
    }
    
    @Override
    public boolean isEmpty() {
        return m.isEmpty();
    }
    
    @Override
    public boolean contains(Object o) {
        return m.containsKey(o);
    }
    
    @Override
    public Object[] toArray() {
        Object[] result = new Object[size()];
        int i = 0;
        for (E e : this) {
            result[i++] = e;
        }
        return result;
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        int size = size();
        if (a.length < size) {
            a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
        }
        int i = 0;
        Object[] result = a;
        for (E e : this) {
            result[i++] = e;
        }
        if (a.length > size) {
            //peculiar toArray contract where it doesn't care about the rest
            a[size] = null;
        }
        return a;
    }
    
    @Override
    public boolean remove(Object o) {
        Node n = m.remove(o);
        if (n != null) {
            n.remove();
            return true;
        }
        return false;
    }
    
    @Override
    public boolean addAll(Collection<? extends E> c) {
        boolean changed = false;
        for (E e : c) {
            changed |= add(e);
        }
        return changed;
    }
    
    @Override
    public boolean containsAll(Collection<?> c) {
        boolean all = true;
        for (Object e : c) {
            all &= m.containsKey(e);
        }
        return all;
    }
    
    @Override
    public boolean retainAll(Collection<?> c) {
        boolean changed = false;
        Iterator<E> it = iterator();
        while (it.hasNext()) {
            E k = it.next();
            if (!c.contains(k)) {
                it.remove();
                changed = true;
            }
        }
        return changed;
    }
    
    @Override
    public void clear() {
        modCount++;
        head.after = head.before = head;
        m.clear();
    }
    
    @Override
    public String toString() {
        return  m.keySet().toString();
    }
    
    //linkedlist node class
    protected final class Node {
    
        Node before, after;
        int relativeLocation;
        //needed for map removal during iteration
        E key;
    
        private void remove() {
            before.after = after;
            after.before = before;
            modCount++;
        }
    
        private void addBefore(Node existingEntry) {
            after = existingEntry;
            before = existingEntry.before;
            before.after = this;
            after.before = this;
            modCount++;
        }
    
        //head const
        public Node() {
            after = before = this;
            relativeLocation = 0;
        }
    
        public Node(E key, int value) {
            this.key = key;
            this.relativeLocation = value;
        }
    }
    
    protected class LinkedKeyIterator implements ListIterator<E> {
    
        Node nextEntry;
        Node lastReturned;
        int expectedModCount = modCount;
    
        public LinkedKeyIterator() {
            nextEntry = head.after;
        }
    
        public LinkedKeyIterator(Node startAt) {
            nextEntry = startAt;
        }
    
        public boolean hasPrevious() {
            return nextEntry.before != head;
        }
    
        public boolean hasNext() {
            return nextEntry != head;
        }
    
        public E next() {
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            if (nextEntry == head) {
                throw new NoSuchElementException();
            }
    
            Node e = lastReturned = nextEntry;
            nextEntry = e.after;
            return e.key;
        }
    
        public E previous() {
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            if (nextEntry.before == head) {
                throw new NoSuchElementException();
            }
    
            Node e = lastReturned = nextEntry.before;
            nextEntry = e;
            return e.key;
        }
    
        public void remove() {
            if (lastReturned == null) {
                throw new IllegalStateException();
            }
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            m.remove(lastReturned.key);
            nextEntry = lastReturned.after;
            lastReturned.remove();
            lastReturned = null;
            expectedModCount = modCount;
        }
    
        @Override
        public void set(E e) {
            if (lastReturned == null) {
                throw new IllegalStateException();
            }
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            if (lastReturned.key.equals(e)) {
                return;
            }
            //remove mapping for key since we are changing it
            m.remove(lastReturned.key);
            //put in the new one
            lastReturned.key = e;
            Node previousKeyOwner = m.put(e, lastReturned);
            if (previousKeyOwner != null) {
                //as it is a list mutation call, guard against stale iterator
                if(nextEntry == previousKeyOwner){
                    nextEntry = nextEntry.after;
                }
                previousKeyOwner.remove();
            }
            //from m.remove and m.put, may help with 2 concurrent iterators on this instance
            //this method may not change modCount if previousKeyOwner is null
            expectedModCount = ++modCount;
        }
    
        @Override
        public void add(E e) {
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            //calculate a good relative location, updating subsequent ones if needed
            int candidateLoc = nextEntry.before.relativeLocation + 1;
            //opsss, it's full
            if (candidateLoc == nextEntry.relativeLocation) {
                iteratorAddStep *= 1.6;
                for (Node current = nextEntry; current != head; current = current.after) {
                    current.relativeLocation = current.relativeLocation + iteratorAddStep;
                }
            }
    
            Node n = m.get(e);
            if (n == null) {
                n = new Node(e, candidateLoc);
                m.put(e, n);
            } else {
                n.relativeLocation = candidateLoc;
                //as it is a list mutation call, guard against stale iterator
                if(nextEntry == n){
                    nextEntry = nextEntry.after;
                }
                n.remove();
            }
            n.addBefore(nextEntry);
            expectedModCount = modCount;//add before changes modCount
        }
    
        @Override
        public int nextIndex() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        @Override
        public int previousIndex() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to slide some (custom) tab-like buttons into view. I don't want them
I have two divs in my app and I want them to have custom
I have a library of custom contols and want them to be availavle without
i want to create an array with 2 keys and i want them in
I have two information and want them to be displayed at the same time.
When someone visits my page I want them to be rerouted to the login
I want to use XML for UI layout and element definition. Want them to
I'm having trouble getting my links the way I want them. Currently, I have
I am teaching programming to my nephews and I want them to improve their
If I have 2 input fields in a jsp and i want them to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.