Implement the additional 5 methods as indicated in the Linke
Implement the additional 5 methods as indicated in the LinkedList file. Test them thoroughly for all exceptional situations and boundary cases. The methods are contains(), get(), remove(), reverseList(), and set().
public class LinkedList<E>
 {
 Node<E> head;
 Node<E> tail;
 int size;
   
 public LinkedList()
 {
 head=null;
 tail=head;
 size=0;
 }
   
 public boolean isEmpty() {
   
 return (size==0);
   
   
   
   
 }
   
 public void addFirst(E val) {
   
 Node<E> first = new Node<E>();
 first.setValue(val);
   
 if (isEmpty() ){
   
 head=first;
 tail=first;
 
 }
   
 else {
 first.setNext(head);
 head.setPrev(first);
 head=first;
   
 }
 size++;
 }
public void printList() {
   
 Node<E> temp;
   
 if (isEmpty()) {
   
 System.out.println(\"list is empty\");
   
   
 }
 else {
   
 temp= head;
 while (temp!=null) {
 System.out.println(temp.getValue());
 temp=temp.getNext();
 
 } ;
   
   
   
   
 }
   
   
   
 }
   
public void addLast (E val) {
 Node<E> last = new Node<E>();
 last.setValue(val);
   
 if (isEmpty()) {
   
 head=last;
 tail=last;
 
 }
 else {
   
 tail.setNext(last);
 last.setPrev(tail);
 tail=last;
 
 }
 size ++;
 
 }
// handle error situations
 // index value has to be >=0 and <=size
 // size()=0 you do special stuff
public void add(int index, E val) {
   
 if ((index>=0)||(index<=size)) {
   
 if (index==0) addFirst(val);
 else if (index==size) addLast(val);
 else {
 int j =0;
 Node<E> temp= head;
 while (j!=index) {
 //System.out.println(temp.getValue());
 temp=temp.getNext();
 j++;
 }
 Node<E> newNode = new Node<E>();
 newNode.setNext(temp);
 newNode.setPrev(temp.getPrev());
 (temp.getPrev()).setNext(newNode);
 // (newNode.getPrev()).setNext(newNode);
 temp.setPrev(newNode);
 newNode.setValue(val);
 size++;
 }
   
   
   
   
 }
   
   
   
 else
 System.out.println (\"index out of bounds ...\");
   
   
   
 }
// handle empty list
 public E removeFirst() {
   
 E val;
   
 if (isEmpty()) {
 System.out.println(\"List empty - nothing to remove\");
 return null;
 }
 else {
 val=head.getValue();
 if (size==1) {
 head=null;   
 tail=null;
 }
 else {
 head=head.getNext();
 head.setPrev(null);
 }
 
 size--;
 return val;
 }
   
   
   
 }
   
   
   
 //handle empty list
 public E removeLast() {
   
 E val=null;
   
 if ((isEmpty())||(size==1)) val=removeFirst();
   
 else {
 val =tail.getValue();
 tail=tail.getPrev();
 tail.setNext(null);
 size--;
   
 }
 return val;
   
   
 }
 // returns true if the linkedlist contains the item val
 // returns false otherwise
 //for testing equality of objects use the equals() method.
 // Assume toString() method exists for val and for items
 // stored in the linked list.
public boolean contains(Object val) {
 
 }
 // Returns:
 //a new LinkedList which contains the elements in the reverse
 // order of this list from head to tail
 // null if the list is empty.
public LinkedList<E> reverseList() {
   
   
 }
//Parameters:
 //index - index of the element to return
 //Returns:
 //the element at the specified position in this list
 //Throws:
 //IndexOutOfBoundsException - if the index is out of range
 // (index < 0 || index >= size())
public E get (int index) {
   
 }
//Parameters:
 //index - the index of the element to be removed
 //Returns:
 //the element previously at the specified position
 //Throws:
 //IndexOutOfBoundsException - if the index is out of range
 //(index < 0 || index >= size())
public E remove(int index) {
   
 }
//Parameters:
 //index - index of the element to replace
 //val - element to be stored at the specified position
 //Returns:
 //the element previously at the specified position
 //Throws:
 //IndexOutOfBoundsException - if the index is out of range
 //(index < 0 || index >= size())
public boolean set(int index, E val) {
   
 }
  
   
   
   
   
   
   
 }
public class Node<E>
 {
 private Node<E> prev;
 private Node<E> next;
 private E item;   
 public Node() {
 
 prev=null;
 next =null;
 item = null;
   
 }
 public void setValue(E value) {
   
 item = value;
   
 }
   
 public void setPrev(Node<E> p) {
 prev =p;
   
   
 }
   
 public void setNext(Node<E> n) {
 next = n;
   
   
 }
   
 public E getValue() {
   
 return item;
   
 }
   
 public Node<E> getPrev() {
   
 return prev;
   
 }
   
 public Node<E> getNext() {
   
 return next;
   
 }
   
 
   
   
   
 }
Solution
// returns true if the linkedlist contains the item val
 // returns false otherwise
 //for testing equality of objects use the equals() method.
 // Assume toString() method exists for val and for items
 // stored in the linked list.
 public boolean contains(Object val) {
Node<E> track = head;
for (int i = 0; i < size ; i++) {
 if(track.getValue().equals(val)) return true;
 }
return false;
 }
// Returns:
 //a new LinkedList which contains the elements in the reverse
 // order of this list from head to tail
 // null if the list is empty.
 public LinkedList<E> reverseList() {
if(size <= 0){
 return null;
 }
Node<E> node = head;
Node<E> prev = null;
 Node<E> current = node;
 Node<E> next = null;
 while (current != null) {
 next = current.getNext();
 current.setNext(prev);
 prev = current;
 current = next;
 }
 node = prev;
 
 LinkedList<E> ans = new LinkedList<E>();
for (int i = 0; i < size ; i ++ ) {
ans.addLast(node.getValue());
 node = node.getNext();
   
 }
return ans;
 }
//Parameters:
 //index - index of the element to return
 //Returns:
 //the element at the specified position in this list
 //Throws:
 //IndexOutOfBoundsException - if the index is out of range
 // (index < 0 || index >= size())
 public E get (int index) {
if(index >= size || index < 0){
 throw new IndexOutOfBoundsException(\"out of range\");
}
Node<E> track = head;
for (int i = 0; i < index ; i++) {
 track = track.getNext();
 }
return track.getValue();
 }
//Parameters:
 //index - the index of the element to be removed
 //Returns:
 //the element previously at the specified position
 //Throws:
 //IndexOutOfBoundsException - if the index is out of range
 //(index < 0 || index >= size())
 public E remove(int index) {
if(index >= size || index < 0){
 throw new IndexOutOfBoundsException(\"out of range\");
}
if(index == 0){
 E temp = head.getValue();
 head = head.getNext();
 return temp;
}
 Node<E> track = head;
for (int i = 0; i < index-1 ; i++) {
 track = track.getNext();
 }
 E temp = track.getNext().getValue();
track.setNext(track.getNext().getNext());
return temp;
 }
 //Parameters:
 //index - index of the element to replace
 //val - element to be stored at the specified position
 //Returns:
 //the element previously at the specified position
 //Throws:
 //IndexOutOfBoundsException - if the index is out of range
 //(index < 0 || index >= size())
 public boolean set(int index, E val) {
 if(index >= size || index < 0){
 throw new IndexOutOfBoundsException(\"out of range\");
}
Node<E> track = head;
for (int i = 0; i < index ; i++) {
 track = track.getNext();
 }
track.setValue(val);
 return true;
 }





