Write a class named Deque20, placed in the file Deque20.java. It should behave exactly as described in the Java interface Deque (Google: \"Java 8 Deque\") except that it should only implement the following methods: a no-argument constructor, addFirst, addLast, removeFirst, removeLast, peekFirst, peekLast, and size. Your class should not extend or implement any class or interface. It must use an array as its storage, allow generic types (E), and be as efficient as possible. The Deque javadoc mentions several exceptions, but you should only return NullPointerException (if someone tries to add a null reference to the Deque) and NoSuchElementException (if someone tries to remove an item from an empty Deque). Your deque should store objects in a circular array. Probably the simplest implementation has objects with fields The meaning being that the elements currently in the deque are at positions list[first_index], list[(first_index+1)%list.length], list[(first_index+2)%list.length],..., list[(first_index+num_elems-1)%list.length]. The modulus is necessary because first_index might be near the end of the array and adding to it might result in an index that\'s out of bounds. When an add operation would cause the capacity of the array to be exceeded, you should double the size of the array by creating a new array of twice the size and copying the old array contents into the new. Do not worry about ever reducing the size of an array. Also, whenever a reference is removed from your deque, the old array location should be set to null so that the garbage collector knows that the old item is no longer referred to by the deque. Solution public class Deque20 { private int first_index; private int num_elems; private Object[] list; Deque20(){ first_index = 0; num_elems = 0; list = new Object[20]; } private void doubleSize(){ Object[] arr = new Object[2 * list.length]; for(int i = 0; i < list.length; ++i){ arr[i] = list[(i + first_index) % list.length]; } list = arr; } public void addFirst(E val){ if(list.length == num_elems){ doubleSize(); } int index = (first_index + list.length - 1) % list.length; list[index] = val; ++num_elems; } public void addLast(E val){ if(list.length == num_elems){ doubleSize(); } int index = (first_index + num_elems) % list.length; list[index] = val; ++num_elems; } public E removeFirst(){ int index = first_index; E ret = (E) list[index]; first_index = (first_index + 1) % list.length; return ret; } public E removeLast(){ int index = ((first_index + num_elems) % list.length) - 1; E ret = (E) list[index]; --num_elems; return ret; } public E peekFirst(){ return (E) list[first_index]; } public E peekLast(){ int index = ((first_index + num_elems) % list.length) - 1; return (E) list[index]; } public int size(){ return num_elems; } }.