content: public class LinkedList {
      private class Node {
          public Integer element;
          public Node next;
  
          public Node(Integer element) {
              this.element = element;
              next = null;
          }
      }
  
      private Node head;
      private Node tail;
      private int count;
  
      /**
       * Construtor da lista
       */
      public LinkedList() {
          head = null;
          tail = null;
          count = 0;
      }
  
      /**
       * Adiciona um elemento ao final da lista
       *
       * @param element elemento a ser adicionado ao final da lista
       */
      public void add(Integer element) {
          Node aux = new Node(element);
          if (head == null) {
              head = aux;
          } else {
              tail.next = aux;
          }
          tail = aux;
          count++;
      }
  
      /**
       * Retorna o elemento de uma determinada posicao da lista
       *
       * @param index a posição da lista
       * @return o elemento da posicao especificada
       * @throws IndexOutOfBoundsException se (index < 0 || index >= size())
       */
      public Integer get(int index) {
          if ((index < 0) || (index >= count)) {
              throw new IndexOutOfBoundsException();
          }
          Node aux = head;
          int c = 0;
          while (c < index) {
              aux = aux.next;
              c++;
          }
          return (aux.element);
      }
  
      /**
       * Substitui o elemento armanzenado em uma determinada posicao da lista pelo
       * elemento indicado
       *
       * @param index   a posicao da lista
       * @param element o elemento a ser armazenado na lista
       * @return o elemento armazenado anteriormente na posicao da lista
       * @throws IndexOutOfBoundsException se (index < 0 || index >= size())
       */
      public Integer set(int index, Integer element) {
          if ((index < 0) || (index >= count)) {
              throw new IndexOutOfBoundsException();
          }
          Node aux = head;
          for (int i = 0; i < index; i++) {
              aux = aux.next;
          }
          Integer tmp = aux.element;
          aux.element = element;
          return tmp;
      }
  
      /**
       * Retorna true se a lista nao contem elementos
       *
       * @return true se a lista nao contem elementos
       */
      public boolean isEmpty() {
          return (head == null);
      }
  
      /**
       * Retorna o numero de elementos da lista
       *
       * @return o numero de elementos da lista
       */
      public int size() {
          return count;
      }
  
      /**
       * Esvazia a lista
       */
      public void clear() {
          head = null;
          tail = null;
          count = 0;
      }
  
      /**
       * Remove o elemento de uma determinada posicao da lista
       *
       * @param index a posicao da lista
       * @return o elemento que foi removido da lista
       * @throws IndexOutOfBoundsException se (index < 0 || index >= size())
       */
      public Integer removeByIndex(int index) {
          if (index < 0 || index >= count) {
              throw new IndexOutOfBoundsException();
          }
  
          Node aux = head;
          if (index == 0) {
              if (tail == head) {
                  tail = null;
              }
              head = head.next;
              count--;
              return aux.element;
          }
          int c = 0;
          while (c < index - 1) {
              aux = aux.next;
              c++;
          }
          Integer element = aux.next.element;
          if (tail == aux.next) {
              tail = aux;
          }
          aux.next = aux.next.next;
          count--;
          return element;
      }
  
      /**
       * Retorna o indice da primeira ocorrencia do elemento na lista, ou -1 se a
       * lista nao contem o elemento
       *
       * @param element o elemento a ser buscado
       * @return o indice da primeira ocorrencia do elemento na lista, ou -1 se a
       *         lista nao contem o elemento
       */
      public int indexOf(Integer element) {
          int index = 0;
          Node aux = head;
          while (aux != null) {
              if (aux.element.equals(element)) {
                  return (index);
              }
              aux = aux.next;
              index++;
          }
          return -1;
      }
  
      /**
       * Retorna true se a lista contem o elemento especificado
       *
       * @param element o elemento a ser testado
       * @return true se a lista contem o elemento especificado
       */
      public boolean contains(Integer element) {
          Node aux = head;
          while (aux != null) {
              if (aux.element.equals(element)) {
                  return (true);
              }
              aux = aux.next;
          }
          return false;
      }
  
      @Override
      public String toString() {
          StringBuilder s = new StringBuilder();
  
          Node aux = head;
  
          while (aux != null) {
              s.append(aux.element.toString());
              s.append("\n");
              aux = aux.next;
          }
  
          return s.toString();
      }
  
  }
  