Since I am using Hackerrank codepair, I have to resort to inner classes. Please review the code and let me know if this can be improved.
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.PriorityQueue;
public class LinkedListMerge {
private List<LinkedList<Integer>> listsToMerge;
private LinkedList<Integer> mergedList;
public LinkedListMerge() {
listsToMerge = new ArrayList<LinkedList<Integer>>();
listsToMerge.add(new LinkedList(new Integer[]{3, 5, 7, 10, 11}));
listsToMerge.add(new LinkedList(new Integer[]{13, 25, 72, 101, 111}));
listsToMerge.add(new LinkedList(new Integer[]{12, 15, 17, 110, 112}));
mergedList = new LinkedList<Integer>();
}
public void mergeLists() {
PriorityQueue<ValueIterator> priorityQueue = new PriorityQueue<ValueIterator>(listsToMerge.size());
for(LinkedList<Integer> linkedList : listsToMerge) {
Iterator<Node<Integer>> currentIterator = linkedList.iterator();
priorityQueue.add(new ValueIterator(currentIterator.next().getValue(), currentIterator));
}
while(priorityQueue.peek() != null) {
ValueIterator minElement = priorityQueue.poll();
mergedList.add((Integer)minElement.getValue());
if(minElement.getIterator().hasNext()) {
Node<Integer> nextElement = ( Node<Integer>)minElement.getIterator().next();
priorityQueue.add(new ValueIterator(nextElement.getValue(), minElement.getIterator()));
}
}
}
public LinkedList getMergedList() {
return mergedList;
}
private class ValueIterator<K extends Comparable> implements Comparable {
K value;
Iterator<K> iterator;
public ValueIterator(K value, Iterator<K> iterator) {
this.value = value;
this.iterator = iterator;
}
public K getValue() {
return value;
}
public Iterator<K> getIterator() {
return iterator;
}
@Override
public int compareTo(Object o) {
return value.compareTo(((ValueIterator)o).getValue());
}
}
public class LinkedList<K extends Comparable> {
private Node<K> head = null;
private Node<K> tail = null;
public LinkedList() {
}
public LinkedList(K[] array) {
head = new Node(array[0], null);
Node<K> currentPointer = head;
for(int i = 1; i < array.length; i++) {
currentPointer.setNext(new Node(array[i], null));
currentPointer = currentPointer.next();
}
tail = currentPointer;
}
public void add(K element) {
if(head == null) {
head = new Node(element, null);
tail = head;
} else {
tail.setNext(new Node(element, null));
tail = tail.next();
}
}
public Iterator<Node<K>> iterator() {
return new Itr(head);
}
@Override
public String toString() {
StringBuffer str = new StringBuffer();
Iterator<Node<K>> itr = iterator();
while(itr.hasNext()) {
Node<K> current = itr.next();
str.append(current.getValue().toString());
str.append("->");
}
return str.toString();
}
private class Itr implements Iterator<Node<K>> {
private Node<K> cursor;
public Itr(Node<K> start) {
cursor = start;
}
@Override
public boolean hasNext() {
return cursor !=null;
}
@Override
public Node<K> next() {
Node<K> currentElement = cursor;
cursor = cursor.next();
return currentElement;
}
@Override
public void remove() {
throw new RuntimeException("Unsupported Operation");
}
}
}
private class Node<K extends Comparable> {
K data;
Node next;
public Node( K data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node node) {
next = node;
}
public Node<K> next() {
return next;
}
public K getValue() {
return data;
}
}
public static void main(String args[]) {
LinkedListMerge llm = new LinkedListMerge();
llm.mergeLists();
System.out.println(llm.getMergedList().toString());
}
}