Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

The implementation of several methods is (or can be) the same between our ArrayList and LinkedList. Write a common abstract superclass called AbstractList that implements

The implementation of several methods is (or can be) the same between our ArrayList and LinkedList. Write a common abstract superclass called AbstractList that implements the common behavior and is extended by both ArrayList and LinkedList. Factor out the common code from the two list classes into this abstract superclass so that no code duplication occurs between the two. Use iterators wherever possible in the abstract code to ensure that the implementation is efficient for both types of lists.

*********************

ArrayList.java

*********************

// Class ArrayList can be used to store a list of values of type E.

import java.util.*;

public class ArrayList implements List {

private E[] elementData;

private int size;

public static final int DEFAULT_CAPACITY = 100;

@SuppressWarnings("unchecked")

public ArrayList(int capacity) {

if (capacity < 0) {

throw new IllegalArgumentException("capacity: " + capacity);

}

elementData = (E[]) new Object[capacity];

size = 0;

}

public ArrayList() {

this(DEFAULT_CAPACITY);

}

public int size() {

return size;

}

public E get(int index) {

checkIndex(index);

return elementData[index];

}

public String toString() {

if (size == 0) {

return "[]";

} else {

String result = "[" + elementData[0];

for (int i = 1; i < size; i++) {

result += ", " + elementData[i];

}

result += "]";

return result;

}

}

public int indexOf(E value) {

for (int i = 0; i < size; i++) {

if (elementData[i].equals(value)) {

return i;

}

}

return -1;

}

public boolean isEmpty() {

return size == 0;

}

public boolean contains(E value) {

return indexOf(value) >= 0;

}

public void add(E value) {

ensureCapacity(size + 1);

elementData[size] = value;

size++;

}

public void add(int index, E value) {

if (index < 0 || index > size) {

throw new IndexOutOfBoundsException("index: " + index);

}

ensureCapacity(size + 1);

for (int i = size; i >= index + 1; i--) {

elementData[i] = elementData[i - 1];

}

elementData[index] = value;

size++;

}

public void remove(int index) {

checkIndex(index);

for (int i = index; i < size - 1; i++) {

elementData[i] = elementData[i + 1];

}

elementData[size - 1] = null;

size--;

}

public void set(int index, E value) {

checkIndex(index);

elementData[index] = value;

}

public void clear() {

for (int i = 0; i < size; i++) {

elementData[i] = null;

}

size = 0;

}

public void addAll(List other) {

for (E value: other) {

add(value);

}

}

public Iterator iterator() {

return new ArrayListIterator();

}

public void ensureCapacity(int capacity) {

if (capacity > elementData.length) {

int newCapacity = elementData.length * 2 + 1;

if (capacity > newCapacity) {

newCapacity = capacity;

}

elementData = Arrays.copyOf(elementData, newCapacity);

}

}

private void checkIndex(int index) {

if (index < 0 || index >= size) {

throw new IndexOutOfBoundsException("index: " + index);

}

}

private class ArrayListIterator implements Iterator {

private int position;

private boolean removeOK;

public ArrayListIterator() {

position = 0;

removeOK = false;

}

public boolean hasNext() {

return position < size();

}

public E next() {

if (!hasNext()) {

throw new NoSuchElementException();

}

E result = elementData[position];

position++;

removeOK = true;

return result;

}

public void remove() {

if (!removeOK) {

throw new IllegalStateException();

}

ArrayList.this.remove(position - 1);

position--;

removeOK = false;

}

}

}

*****************

LinkedList.java

*****************

import java.util.*;

public class LinkedList implements List {

private ListNode front;

private ListNode back;

private int size;

public LinkedList() {

front = new ListNode(null);

back = new ListNode(null);

clear();

}

public int size() {

return size;

}

public E get(int index) {

checkIndex(index);

ListNode current = nodeAt(index);

return current.data;

}

public String toString() {

if (size == 0) {

return "[]";

} else {

String result = "[" + front.next.data;

ListNode current = front.next.next;

while (current != back) {

result += ", " + current.data;

current = current.next;

}

result += "]";

return result;

}

}

public int indexOf(E value) {

int index = 0;

ListNode current = front.next;

while (current != back) {

if (current.data.equals(value)) {

return index;

}

index++;

current = current.next;

}

return -1;

}

public boolean isEmpty() {

return size == 0;

}

public boolean contains(E value) {

return indexOf(value) >= 0;

}

public void add(E value) {

add(size, value);

}

public void add(int index, E value) {

if (index < 0 || index > size) {

throw new IndexOutOfBoundsException("index: " + index);

}

ListNode current = nodeAt(index - 1);

ListNode newNode = new ListNode(value, current.next, current);

current.next = newNode;

newNode.next.prev = newNode;

size++;

}

public void addAll(List other) {

for (E value: other) {

add(value);

}

}

public void remove(int index) {

checkIndex(index);

ListNode current = nodeAt(index - 1);

current.next = current.next.next;

current.next.prev = current;

size--;

}

public void set(int index, E value) {

checkIndex(index);

ListNode current = nodeAt(index);

current.data = value;

}

public void clear() {

front.next = back;

back.prev = front;

size = 0;

}

public Iterator iterator() {

return new LinkedIterator();

}

private ListNode nodeAt(int index) {

ListNode current;

if (index < size / 2) {

current = front;

for (int i = 0; i < index + 1; i++) {

current = current.next;

}

} else {

current = back;

for (int i = size; i >= index + 1; i--) {

current = current.prev;

}

}

return current;

}

private void checkIndex(int index) {

if (index < 0 || index >= size()) {

throw new IndexOutOfBoundsException("index: " + index);

}

}

private static class ListNode {

public E data;

public ListNode next;

public ListNode prev;

public ListNode(E data, ListNode next, ListNode prev) {

this.data = data;

this.next = next;

this.prev = prev;

}

public ListNode(E data) {

this(data, null, null);

}

}

private class LinkedIterator implements Iterator {

private ListNode current;

private boolean removeOK;

public LinkedIterator() {

current = front.next;

removeOK = false;

}

public boolean hasNext() {

return current != back;

}

public E next() {

if (!hasNext()) {

throw new NoSuchElementException();

}

E result = current.data;

current = current.next;

removeOK = true;

return result;

}

public void remove() {

if (!removeOK) {

throw new IllegalStateException();

}

ListNode prev2 = current.prev.prev;

prev2.next = current;

current.prev = prev2;

size--;

removeOK = false;

}

}

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Samsung Galaxy S23 Ultra Comprehensive User Manual

Authors: Leo Scott

1st Edition

B0BVPBJK5Q, 979-8377286455

More Books

Students also viewed these Databases questions