Простой, забавный, легко связанный стек списков в Java

(См. также следующую итерацию.)

(Эта структура данных может быть реализована как Deque<List<T>>, все же я решил иметь некоторое лучшее время с этим. :-))

com.github.coderodde.util.Multistack.java:

package com.github.coderodde.util;

import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * This class implements a stack of lists.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (Feb 8, 2023)
 * @since 1.6 (Feb 8, 2023)
 */
public final class Multistack<T> implements Iterable<List<T>> {
    
    private static final class MultistackIterator<T> 
            implements Iterator<List<T>> {

        private final Multistack<T> stack;
        private final long expectedModCount;
        private MultistackNode<T> currentNode;

        MultistackIterator(Multistack<T> stack) {
            this.stack = stack;
            this.expectedModCount = stack.modCount;
            this.currentNode = stack.top;
        }

        @Override
        public boolean hasNext() {
            checkModCount();
            return currentNode != null;
        }

        @Override
        public List<T> next() {
            checkModCount();
            List<T> list = currentNode.extract();
            currentNode = currentNode.next;
            return list;
        }
        
        private void checkModCount() {
            if (expectedModCount != stack.modCount) {
                throw new ConcurrentModificationException(
                        "Multistack changed while iterating.");
            }
        }
    }

    @Override
    public Iterator<List<T>> iterator() {
        return new MultistackIterator<>(this);
    }

    private static final class Node<T> {
        private final T datum;
        private Node<T> next;
        
        Node(T datum) {
            this.datum = datum;
        }
    }
    
    private static final class MultistackNode<T> {
        private final Node<T> head;
        private Node<T> tail;
        private final MultistackNode<T> next;
        private int size = 0;

        public MultistackNode(T datum, MultistackNode<T> top) {
            Node<T> node = new Node<>(datum);
            head = node;
            tail = node;
            size = 1;
            next = top;
            top = this;
        }
        
        void append(Node<T> node) {
            tail.next = node;
            tail = node;
            size++;
        }
        
        List<T> extract() {
            List<T> list = new ArrayList<>(size);
            
            for (Node<T> node = head; node != null; node = node.next) {
                list.add(node.datum);
            }
            
            return list;
        }
    }
    
    private int size;
    private long modCount;
    private MultistackNode<T> top;
    
    public void push(T datum) {
        MultistackNode node = new MultistackNode(datum, top);
        top = node;
        size++;
        modCount++;
    }
    
    public void linkToTop(T datum) {
        if (size == 0) {
            throw new NoSuchElementException(
                    "Trying to link a datum to an empty Multistack. " + 
                    "Please push an element before doing this operation.");
        }
        
        top.append(new Node<>(datum));
        modCount++;
    }
    
    public List<T> peek() {
        if (size == 0) {
            throw new NoSuchElementException(
                    "Peeking from an empty Multistack.");
        }
        
        return top.extract();
    }
    
    public List<T> pop() {
        if (size == 0) {
            throw new NoSuchElementException(
                    "Popping from an empty Multistack.");
        }
        
        List<T> returnValue = top.extract();
        top = top.next;
        size--;
        modCount++;
        return returnValue;
    }
    
    public int size() {
        return size;
    }
    
    public boolean isEmpty() {
        return size == 0;
    }
    
    public static void main(String[] args) {
        Multistack<Integer> stack = new Multistack<>();
        
        stack.push(1);
        stack.push(2);
        stack.linkToTop(3);
        stack.linkToTop(4);
        stack.push(5);
        stack.linkToTop(6);
        stack.push(7);
        
        for (List<Integer> level : stack) {
            System.out.println(level);
        }
    }
}

Демонстрационный вывод

[7]
[5, 6]
[2, 3, 4]
[1]

Запрос критики

Есть что улучшить? Пожалуйста, скажите мне.

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *