// Añade un elemento a la lista (en el lugar de orden que le corresponde)
  public void add(T elem) {
    DoubleNode<T> nuevo = new DoubleNode<T>(elem);
    DoubleNode<T> actual = first;

    while (actual != null && actual.getElement().compareTo(elem) < 0)
    // La lista no es vacía Y no ha encontrado la posición
    {
      actual = actual.getNext();
    }
    if (actual == null) { // la lista es vacía o se inserta al final
      if (first != null) { // insertar al final
        last.setNext(nuevo);
        nuevo.setPrevious(last);
        last = nuevo;
      } else { // la lista es vacía
        last = nuevo;
        first = nuevo;
      }
    } else if (actual == first) { // inserción al principio
      nuevo.setNext(first);
      first.setPrevious(nuevo);
      first = nuevo;
    } else {
      nuevo.setNext(actual);
      nuevo.setPrevious(actual.getPrevious());
      actual.setPrevious(nuevo);
      nuevo.getPrevious().setNext(nuevo);
    }
    length++;
  }
 // Devuelve true si esta lista contiene el elemento especificado
 public boolean contains(T target) {
   if (length == 0) return false;
   else {
     DoubleNode<T> actual = first;
     while (actual != null && (!actual.getElement().equals(target))) // buscamos el elemento
     actual = actual.getNext();
     if (actual == null) return false;
     else return true;
   }
 }
 // Elimina y devuelve el elemento especificado de la lista
 public T remove(T element) {
   if (length > 0) {
     DoubleNode<T> actual = first;
     while (actual != null && !actual.getElement().equals(element)) // buscamos el elemento
     actual = actual.getNext();
     // actual apunta al elemento buscado o a null
     if (actual == null) return null;
     else // (actual.data.equals(element))  element está en la lista
     if (actual == first) return removeFirst();
     else if (actual == last) return removeLast();
     else {
       actual.getNext().setPrevious(actual.getPrevious());
       actual.getPrevious().setNext(actual.getNext());
       length--;
       return (actual.getElement());
     }
   } else // Si llega aquí es que length == 0
   return null;
 }
 // Elimina y devuelve el último elemento de la lista
 public T removeLast() {
   if (length > 0) {
     DoubleNode<T> temp = last;
     if (length == 1) // la lista tiene sólo un elemento
     first = null;
     else last.getPrevious().setNext(null);
     last = last.getPrevious();
     length--;
     return temp.getElement();
   } else return null;
 }
  @Override
  public void add(T element) {
    Comparable temp = (Comparable) element;

    DoubleNode e = new DoubleNode(element);
    DoubleNode tt;

    boolean found = false;
    // se vazia
    if (isEmpty()) {
      super.setRear(e);
      super.setFront(e);

    } else {
      tt = super.getFront();

      while (tt != null && !found) {
        if (temp.compareTo(tt.getElement()) > 0) {
          tt = tt.getNext();
        } else {
          found = true;
        }
      }
      // adicionar a cauda
      if (tt == null) {

        super.getRear().setNext(e);
        e.setPrevious(super.getRear());
        super.setRear(e);
        // adicionar a front
      } else if (tt.equals(super.getFront())) {

        e.setNext(super.getFront());
        super.getFront().setPrevious(e);
        super.setFront(e);

      } else {
        // adicionar ao meio
        e.setPrevious(tt.getPrevious());
        e.setNext(tt);
        tt.setPrevious(e);
        e.getPrevious().setNext(e);
      }
    }
    super.setCount(super.getCount() + 1);
  }
 // Devuelve una referencia al último elemento de la lista
 public T last() {
   if (length > 0) return last.getElement();
   else return null;
 }
 // Devuelve una referencia al primer elemento de la lista
 public T first() {
   if (length > 0) return (first.getElement());
   else return null;
 }