美文网首页
自定义ArrayList&LinkedList

自定义ArrayList&LinkedList

作者: LHZ_123 | 来源:发表于2021-05-15 13:27 被阅读0次

接口定义

public interface MyList<T> extends Iterable<T>{
    void add(T element);

    void add(int index, T element);

    void remove(Object element);

    T remove(int index);

    T get(int index);

    int indexOf(T element);

    int size();
}

基于数组实现ArrayList

public class MyArrayList<T> implements MyList<T> {
    private static final int DEFAULT_SIZE = 10;

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private transient Object[] elementData;

    private int size;

    public MyArrayList() {
        elementData = new Object[DEFAULT_SIZE];
    }

    public MyArrayList(int capacity) {
        if (capacity > 0) {
            elementData = new Object[capacity];
        } else if (capacity == 0) {
            elementData = new Object[0];
        } else {
            throw new IllegalArgumentException("illegal capacity " + capacity);
        }

        elementData = new Object[capacity];
    }

    @Override
    public void add(T element) {
        ensureCapacity(size + 1);
        elementData[size++] = element;
    }

    private void ensureCapacity(int minCapacity) {
        if (minCapacity > elementData.length) {
            if (minCapacity < DEFAULT_SIZE) {
                minCapacity = DEFAULT_SIZE;
            }

            grow(minCapacity);
        }
    }

    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity < 0) {
            throw new OutOfMemoryError();
        }

        if (newCapacity < minCapacity) {
            newCapacity = minCapacity;
        }

        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    @Override
    public void add(int index, T element) {
        if (index >= size || index < 0) {
            throw new IndexOutOfBoundsException();
        }
        ensureCapacity(size + 1);
        System.arraycopy(elementData, index, elementData, index + 1, size - index);
        elementData[index] = element;
        size++;
    }

    @Override
    public void remove(Object element) {
        for (int i = 0; i < size; i++) {
            if (Objects.equals(element, elementData[i])) {
                remove(i);
                return;
            }
        }
    }

    @Override
    public T remove(int index) {
        if (index >= size) {
            throw new IndexOutOfBoundsException();
        }
        T oldElement = (T) elementData[index];
        System.arraycopy(elementData, index + 1, elementData, index, size - index - 1);
        elementData[--size] = null; //for gc

        return oldElement;
    }

    @Override
    public T get(int index) {
        if (index >= size) {
            throw new IndexOutOfBoundsException();
        }

        return (T) elementData[index];
    }

    @Override
    public int indexOf(T element) {
        for (int i = 0; i < size; i++) {
            if (Objects.equals(element, elementData[i])) {
                return i;
            }
        }
        return 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            private int cursor;

            @Override
            public boolean hasNext() {
                return cursor != size;
            }

            @Override
            public T next() {
                return (T) elementData[cursor++];
            }
        };
    }
}

基于链表实现LinkedList

public class MyLinkedList<T> implements MyList<T> {
    private int size;

    private Node<T> first;

    private Node<T> last;

    @Override
    public void add(T element) {
        Node<T> l = last;
        Node<T> newNode = new Node<>(l, element, null);
        last = newNode;
        if (l == null) {
            first = newNode;
        } else {
            l.next = newNode;
        }
        size++;
    }

    @Override
    public void add(int index, T element) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException(String.valueOf(index));
        }

        if (index == size) {
            add(element);
        } else {
            Node<T> node = getNode(index);
            Node<T> prev = node.prev;
            Node<T> newNode = new Node<>(prev, element, node);
            prev.next = newNode;
            node.prev = newNode;
            size++;
        }
    }

    @Override
    public void remove(Object element) {
        int nodeIndex = findNodeIndex(element);
        if (nodeIndex > 0) {
            remove(nodeIndex);
        }
    }

    private int findNodeIndex(Object element) {
        Node node = first;
        int index = 0;
        while (node != null) {
            Node next = node.next;
            if (Objects.equals(element, node.item)) {
                return index;
            }
            node = next;
            index++;
        }

        return -1;
    }

    private void removeNode(Node node) {
        Node prev = node.prev;
        Node next = node.next;
        if (prev != null) {
            prev.next = next;
        }
        if (next != null) {
            next.prev = prev;
        }
        node = null;//For gc
        size--;
    }

    @Override
    public T remove(int index) {
        Node<T> node = getNode(index);
        removeNode(node);
        return node.item;
    }

    @Override
    public T get(int index) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException(String.valueOf(index));
        }

        return getNode(index).item;
    }

    private Node<T> getNode(int index) {
        if (index < (size >> 1)) {
            Node<T> node = first;
            for (int i = 1; i <= index; i++) {
                node = node.next;
            }
            return node;
        } else {
            Node<T> node = last;
            for (int i = 1; i <= size - index - 1; i++) {
                node = node.prev;
            }
            return node;
        }
    }

    @Override
    public int indexOf(T element) {
        int nodeIndex = findNodeIndex(element);
        return nodeIndex;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            private Node cur = first;
            @Override
            public boolean hasNext() {
                return cur != null;
            }

            @Override
            public T next() {
                Object item = cur.item;
                cur = cur.next;
                return (T) item;
            }
        };
    }

    private static class Node<T> {
        private T item;
        private Node<T> next;
        private Node<T> prev;

        public Node(Node<T> prev, T item, Node<T> next) {
            this.prev = prev;
            this.item = item;
            this.next = next;
        }
    }
}

相关文章

  • 自定义ArrayList&LinkedList

    接口定义 基于数组实现ArrayList 基于链表实现LinkedList

  • Dialog

    安卓dialog的使用+如何自定义dialog自定义Dialog自定义Dialog 自定义

  • django的自定义filter和自定义simple_tag

    django的自定义filter和自定义simple_tag 自定义filter: 自定义filter: 简单示例...

  • 自定义tabbarController

    要自定义tabBarController,就要自定义tabBar.要自定义tabBar就要自定义item.所以,咱...

  • 第三方

    ZYSideSlipFilter 侧边栏条件筛选器,支持自定义事件,自定义筛选栏目,自定义所有。。。样式完全自定义...

  • Android 高德地图 自定义Location小蓝点

    设置自定义定位蓝点 自定义Location小蓝点,自定义功能

  • vue 有自定义指令

    vue 的自定义指令,分为全局自定义指令和局部自定义指令,局部自定义指令等价于局部组件。 自定义指令可以对DOM进...

  • Android相关知识点博客记录

    自定义属性 Android自定义View(二、深入解析自定义属性) Android中XML的命名空间、自定义属性 ...

  • CocoaLumberjack源码分析

    1.使用 自定义custom context,自定义flag 自定义日志的格式 自定义日志级别,取消DDLog实现...

  • Android View(转)

    自定义View的原理自定义View基础 - 最易懂的自定义View原理系列自定义View Measure过程 - ...

网友评论

      本文标题:自定义ArrayList&LinkedList

      本文链接:https://www.haomeiwen.com/subject/gbwhjltx.html