view src/main/java/jp/ac/u_ryukyu/ie/cr/list/List.java @ 204:ce00e580cc44

List implement append
author tatsuki
date Tue, 19 May 2015 12:07:24 +0900
parents 1833956aea55
children 89df000def32
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.list;

import java.util.Iterator;
import java.util.Stack;

/**
 * Created by e115731 on 15/05/16.
 * 非破壊であるためこのListは逆順になっています
 */
public class List<T> implements Iterable<T> {
    final Node<T> head;
    final int listLength;

    public List() {
        this.head = new headNode(null);
        this.listLength = 0;
    }


    private List(Node<T> head) {
        this.head = head;
        this.listLength = head.getNext().getNum();
    }


    public List<T> add(int num, T attribute) {
        Node<T> newNode = head.getNext().add(num, attribute);
        if (newNode == null)
            return this;
        Node<T> newHead = new headNode<>(newNode);
        return new List<T>(newHead);
    }

    public List<T> addLast(T attribute) {
        Node newNode = new DefaultNode(attribute, listLength + 1, head.getNext());
        Node newHead = new headNode(newNode);
        return new List(newHead);
    }

    public T index(int num) {
        Node<T> currentNode = head.getNext();
        while (currentNode.getNum() != -1) {
            if (currentNode.getNum() == num)
                return currentNode.getAttribute();
            currentNode = currentNode.getNext();
        }
        return null;
    }

    public Iterator<T> iterator() {
        return new Iterator<T>() {
            Node<T> currentNode = head.getNext();

            @Override
            public boolean hasNext() {
                return currentNode.getNum() != -1;
            }

            @Override
            public T next() {
                T attribute = currentNode.getAttribute();
                currentNode = currentNode.getNext();
                return attribute;
            }
        };
    }

    public Iterator<T> reverseIterator() {
        Node<T> currentNode = head.getNext();
        Stack<T> stack = new Stack();
        while (currentNode.getNum() != -1) {
            stack.push(currentNode.getAttribute());
            currentNode = currentNode.getNext();
        }
        return new Iterator<T>() {

            @Override
            public boolean hasNext() {
                return !stack.isEmpty();
            }

            @Override
            public T next() {
                return stack.pop();
            }
        };
    }


    public List<T> delete(int num) {
        Node<T> newNode = head.delete(num);
        if (newNode == null)
            return this;
        Node<T> newHead = new headNode<>(newNode);
        return new List<T>(newNode);
    }

    public List<T> replace(int num, T attribute) {
        Node<T> newNode = head.getNext().replaceNode(num, attribute);
        if (newNode == null)
            return this;
        Node<T> newHead = new headNode<>(newNode);
        return new List<T>(newHead);
    }

    public T last() {
        return head.getNext().getAttribute();
    }

    public T head() {
        return index(1);
    }

    public List<T> deleteLast() {
        return delete(listLength);
    }

    public List<T> deleteHead() {
        return delete(1);
    }

    public int length() {
        return listLength;
    }

    @Override
    public String toString() {
        String pathString = "<";
        Iterator<T> iterator = reverseIterator();
        while (true) {
            pathString += iterator.next();
            if (iterator.hasNext())
                pathString += ",";
            else
                break;
        }
        pathString += ">";
        return pathString;
    }

    public List<T> append(List<T> list) {
        Iterator<T> iterator = list.reverseIterator();
        List<T> newList = this;
        while (iterator.hasNext()) {
            T attribute = iterator.next();
            newList = newList.addLast(attribute);
        }
        return newList;
    }
}