Last active
April 26, 2017 22:41
-
-
Save telendt/fe7e30ac6ef1d17bc9c18f28159bcfe0 to your computer and use it in GitHub Desktop.
k-way MergeIterator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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