Реализация пользовательского LinkedArrayList с расширением AbstractList - PullRequest
1 голос
/ 27 марта 2020

Определение проблемы

  • Мне нужна коллекция, в которой есть узлы, и каждый узел имеет частично заполненный массив постоянного размера. Каждый массив может содержать различный размер, если он меньше ранее определенного постоянного размера. Будет список этих узлов.

Например:

  • Когда элемент необходимо добавить в список, список добавляет элемент в первом соответствующем узле, который не заполнен. Если я постоянно добавить (1) , добавить (2) , добавить (3) , добавить (4) , Список add (1) , будет показан следующим образом:
  • Предположим, DEFAULT_NODE_CAPACITY = 3
    • node-0 -> "123 "
    • node-1 ->" 41 "

  • Когда необходимо удалить элемент из списка list удаляет элемент из первого соответствующего узла, который содержит и соответствует данному элементу. Если i удалить (1) из списка, список будет отображаться так:
    • node-0 -> "23"
    • node-1 -> "41"

Что я пробовал?

  • Я рассмотрел использование внутренний класс, который является stati c one, потому что класс узла не должен обращаться к полям и методам внешнего класса. Все типы должны быть generi c, поэтому я поместил значение ключа generic c, идентичное для каждого конструктора.
  • Критическим моментом было то, что мне пришлось использовать класс AbstractList в моей пользовательской коллекции. На этом этапе Я действительно не понимаю, какую структуру я буду использовать для вызова класса узла с частично фиксированным массивом.

Вопросы

  • Как переопределить Методы AbstractList, которые соответствуют внутреннему классу моего узла. Когда я читаю Java API-документацию , для создания модифицируемого мне просто нужно переопределить

    • get ()
    • set ()
    • remove ()
    • add ()
    • size () на данный момент, как я могу эффективно переопределить их все, соответствуя моему определению проблемы?
  • Какой тип данных я должен использовать для вызова Node<E>? и как можно это реализовать?


Как я реализовал?

package edu.gtu.util;

import java.util.AbstractList;
import java.util.Collection;
import java.util.List;

public class LinkedArrayList<E> extends AbstractList<E>
        implements List<E> , Collection<E>, Iterable<E> {

    public static final int DEFAULT_CAPACITY = 10;
    public static final int CONSTANT_NODE_CAPACITY = 3;

    /* Is that wrong ? , how to be conformed to AbstractList ? */
    private Node<E>[] listOfNode = null;
    /*---------------------------------------------------------*/

    private int size;

    private static class Node<E> {

        private Object[] data;
        private Node<E> next = null;
        private Node<E> previous = null;

        private Node( Object[] data , Node<E> next , Node<E> previous ) {

            setData(data);
            setNext(next);
            setPrevious(previous);

        }

        private Node( Object[] data ) {
            this( data , null , null );
        }

        private void setData( Object[] data ) {
            this.data = data;
        }
        private void setNext( Node<E> next ) {
            this.next = next;
        }
        private void setPrevious( Node<E> previous ) {
            this.previous = previous;
        }

        private Object[] getData() {
            return data;
        }
        private Node<E> getNext() {
            return next;
        }
        private Node<E> getPrevious() {
            return previous;
        }

    }


    private void setSize( int size ) {
        this.size = size;
    }

    public LinkedArrayList() {
        super();
    }

    public LinkedArrayList( int size ) {
        super();

        setSize( size );
        listOfNode = (Node<E>[]) new Object[size()];
    }

    public LinkedArrayList(Collection<E> collection ) {
        super();
    }

    @Override
    public E get( int i ) {
    }

    @Override
    public boolean add(E e) {
        return super.add(e);
    }

    @Override
    public boolean remove(Object o) {
        return super.remove(o);
    }

    @Override
    public E set(int index, E element) {
        return super.set(index, element);
    }

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

}

1 Ответ

0 голосов
/ 27 марта 2020

Сначала вам нужно добавить поле к Node, которое сообщит вам, сколько элементов данных хранится в этом узле.

Затем:

  • size должен перебирать узлы и вычислять сумму размеров узлов. Или вы можете сохранить отдельный размер и обновлять его при каждом добавлении и удалении.

  • add должен найти узел, в который можно вставить элемент. Если в этом узле есть место, просто добавьте его туда. Если этот узел заполнен, вы должны создать новый узел.

  • remove должен найти нужный узел и удалить предмет из этого узла. Если узел становится пустым, сам узел можно удалить.

  • get должен выполнять итерацию по узлам, отслеживая, сколько элементов он пропускает, пока не найдет узел должен содержать узел.

  • set - аналогично get, за исключением того, что он заменяет элемент в дополнение к его возврату

В википедии вы найдете лучшие описания: https://en.wikipedia.org/wiki/Unrolled_linked_list В этой статье также предлагается важная оптимизация для добавления / удаления.

...