/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mylinkedlistv2;
import java.util.Iterator;
import java.util.List;
/**
*
* @author Vo Hoang Tu - CE000000
*/
public class SinglyLinkedList<T> implements Iterable<T> {
Node<T> head;
Node<T> tail;
public SinglyLinkedList() {
head = null;
tail = null;
}
public boolean isEmpty() {
// if(head == null) return true;
// else return false;
return head == null;
}
public int size() {
if (isEmpty()) {
return 0;
}
int count = 0;
Node<T> currentNode = head;
while (currentNode != null) {
count++;
currentNode = currentNode.next;
}
return count;
}
public void clear() {
head = tail = null;
}
private void addFirst(T data) {
Node<T> newNode = new Node<>(data);
if (isEmpty()) {
// head = newNode;
// tail = newNode;
head = tail = newNode;
} else {
newNode.next = head;
head = newNode;
}
}
private void addLast(T data) {
Node<T> newNode = new Node(data);
if (isEmpty()) {
head = tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
}
public void add(T data) {
addLast(data);
}
public void add(T[] arr) {
for (T x : arr) {
add(x);
}
}
public void add(List<T> list) {
for (T x : list) {
add(x);
}
}
public void add(T data, int index) {
if (index < 0 || index > size()) {
throw new IllegalArgumentException("Invalid index");
}
Node<T> newNode = new Node<>(data);
if (index == 0) {
addFirst(data);
}
if (index == size()) {
addLast(data);
}
int i = 0;
Node<T> currentNode = head;
while (i != index - 1) {
i++;
currentNode = currentNode.next;
}
newNode.next = currentNode.next;
currentNode.next = newNode;
}
public T removeFirst() {
if (isEmpty()) {
throw new RuntimeException("An empty singly linked list!");
}
T data = head.data;
if (head == tail) {
head = tail = null;
return data;
}
head = head.next;
return data;
}
public T removeLast() {
if (isEmpty()) {
throw new RuntimeException("An empty singly linked list!");
}
T data = tail.data;
if (head == tail) {
head = tail = null;
return data;
}
Node<T> currentNode = head;
while (currentNode.next != tail) {
currentNode = currentNode.next;
}
tail = currentNode;
currentNode.next = null;
return data;
}
public T remove(int index) {
if (index < 0 || index > size() - 1) {
throw new IllegalArgumentException("Invalid index");
}
if (index == 0) {
return removeFirst();
}
if (index == size() - 1) {
return removeLast();
}
Node<T> curentNode = head;
Node<T> parentNode = null;
int i = 0;
while (i != index) {
i++;
parentNode = curentNode;
curentNode = curentNode.next;
}
T data = curentNode.data;
parentNode.next = curentNode.next;
return data;
}
public T getFirst() {
if (isEmpty()) {
throw new RuntimeException("An empty singly linked list!!!");
}
return head.data;
}
public T getLast() {
if (isEmpty()) {
throw new RuntimeException("An empty singly linked list!!!");
}
return tail.data;
}
public T get(int index) {
if (index < 0 || index > size() - 1) {
throw new IllegalArgumentException("Invalid index!!");
}
if (index == 0) {
return getFirst();
}
if (index == size() - 1) {
return getLast();
}
Node<T> currentNode = head;
int i = 0;
while (i != index) {
i++;
currentNode = currentNode.next;
}
return currentNode.data;
}
public int indexOf(Object o) {
if (isEmpty()) {
throw new RuntimeException("An empty singly linkedlist!");
}
Node<T> currentNode = head;
int i = 0;
while (currentNode != null) {
if (currentNode.data == o) {
return i;
}
i++;
currentNode = currentNode.next;
}
return -1;
}
public boolean contain(Object o) {
return indexOf(o) != -1;
}
//[7,5,9,10,12,34]
@Override
public String toString() {
String res = "";
Node<T> currentNode = head;
while (currentNode != null) {
res += currentNode.data + ",";
currentNode = currentNode.next;
}
//7,5,9,10,12,34,
return "[" + res.substring(0, res.length() - 1) + "]";
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
Node<T> currentNode = head;
@Override
public boolean hasNext() {
return currentNode != null;
}
@Override
public T next() {
T data = currentNode.data;
currentNode = currentNode.next;
return data;
}
};
}