Skip to content

Instantly share code, notes, and snippets.

@telendt
Last active April 26, 2017 22:41
Show Gist options
  • Save telendt/fe7e30ac6ef1d17bc9c18f28159bcfe0 to your computer and use it in GitHub Desktop.
Save telendt/fe7e30ac6ef1d17bc9c18f28159bcfe0 to your computer and use it in GitHub Desktop.
k-way MergeIterator
package com.telendt;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class MergeIterator<T extends Comparable<T>> implements Iterator<T> {
final private class Item implements Comparable<Item> {
private T currentValue;
final private Iterator<T> iterator;
private Item(final Iterator<T> iterator) {
this.iterator = iterator;
}
private boolean shift() {
if (iterator.hasNext()) {
currentValue = iterator.next();
return true;
}
return false;
}
@Override
public int compareTo(final Item o) {
return currentValue.compareTo(o.currentValue);
}
}
private final Collection<Item> items;
private final PriorityQueue<Item> queue;
private MergeIterator(Stream<Iterator<T>> s) {
items = s.map(Item::new).collect(Collectors.toList());
queue = new PriorityQueue<>();
}
@SafeVarargs
MergeIterator(final Iterator<T>... iterators) {
this(Arrays.stream(iterators));
}
@SafeVarargs
MergeIterator(final Iterable<T>... iterables) {
this(Arrays.stream(iterables).map(Iterable::iterator));
}
private void initialize() {
for (Item i : items) {
if (i.shift()) {
queue.add(i);
}
}
items.clear();
}
@Override
public boolean hasNext() {
if (items.size() > 0) {
initialize();
}
return queue.size() > 0;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
final Item item = queue.poll();
final T value = item.currentValue;
if (item.shift()) {
queue.add(item);
}
return value;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
public static void main(String[] args) {
final Iterator<Integer> it = new MergeIterator<>(
Arrays.asList(1, 3, 3, 6, 8),
Arrays.asList(0, 1, 5, 7, 10)
);
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment