Skip to content

Instantly share code, notes, and snippets.

@peczenyj
Last active January 4, 2016 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peczenyj/8647049 to your computer and use it in GitHub Desktop.
Save peczenyj/8647049 to your computer and use it in GitHub Desktop.
Frequency Iterator, lazy, in java, with homemade unit test framework (for fun)
import java.util.Iterator;
import java.util.Queue;
import java.util.LinkedList;
import java.util.NoSuchElementException;
class SingleFrequencyIterator<V> implements Iterator<V>{
private int counter;
private V value;
public SingleFrequencyIterator(int frequency, V value) {
if(frequency <= 0) {
throw new IllegalArgumentException("frequency should be a non zero positive number");
}
this.counter = frequency;
this.value = value;
}
public V next() {
if(! this.hasNext() ) throw new NoSuchElementException();
this.counter--;
return this.value;
}
public boolean hasNext(){
return this.counter > 0;
}
public void remove() { throw new UnsupportedOperationException(); }
}
public class FrequencyIterator<V> implements Iterator<V>{
private Iterator<V> head;
private Iterator<V> tail;
private Queue<Iterator<V>> listOfIterators;
public FrequencyIterator(int[] frequencies, V[] values){
if (frequencies.length != values.length) {
throw new IllegalArgumentException("size of frequencies and values should be equal");
}
this.listOfIterators = new LinkedList<Iterator<V>>();
for(int i=0;i < frequencies.length ; i++){
if(frequencies[i] < 0) {
throw new IllegalArgumentException("frequencies should be an array of positive integers or 0");
}
if(frequencies[i] == 0) continue;
this.tail = new SingleFrequencyIterator<V>(frequencies[i], values[i]);
this.listOfIterators.add(this.tail);
}
this.head = listOfIterators.peek();
}
public V next() {
if(! this.hasNext() ) throw new NoSuchElementException();
if(! this.head.hasNext()){
this.listOfIterators.remove();
this.head = this.listOfIterators.peek();
}
return this.head.next();
}
public boolean hasNext(){
return !this.listOfIterators.isEmpty() && this.tail.hasNext();
}
public void remove() { throw new UnsupportedOperationException(); }
public static void main(String [] args) {
int[] frequencies = new int[]{1,0,2,0};
Integer[] values = new Integer[]{4,0,5,0};
Iterator<Integer> freq_it = new FrequencyIterator<Integer>(frequencies,values);
System.out.println("Subtest normal case, with valid numbers");
ok(freq_it.hasNext(), "should has next");
is(freq_it.next(), 4, "should return 4");
ok(freq_it.hasNext(), "should has next");
is(freq_it.next(), 5, "should return 5");
ok(freq_it.hasNext(), "should has next");
is(freq_it.next(), 5, "should return 5 again");
ok(! freq_it.hasNext(), "should return false (end)");
try {
freq_it.next();
fail("should throw exception NoSuchElementException, but does not throw!");
} catch(NoSuchElementException e){
pass("should throw exception NoSuchElementException! yay!");
} catch(Exception e){
fail("should throw exception NoSuchElementException, but throw " + e);
}
System.out.println("Subtest should throw if size of arrays are different");
try {
new FrequencyIterator<Integer>(new int[]{1,0,2,0},new Integer[]{4,0,5});
fail("should throw exception IllegalArgumentException, but does not throw!");
} catch (IllegalArgumentException e) {
pass("should throw exception IllegalArgumentException! yay!" + e);
} catch(Exception e){
fail("should throw exception IllegalArgumentException, but throw " + e);
}
System.out.println("Subtest should throw if frequencies has negative numbers");
try {
new FrequencyIterator<Integer>(new int[]{1,0,-2},new Integer[]{4,0,5});
fail("should throw exception IllegalArgumentException, but does not throw!");
} catch (IllegalArgumentException e) {
pass("should throw exception IllegalArgumentException! yay!" + e);
} catch(Exception e){
fail("should throw exception IllegalArgumentException, but throw " + e);
}
System.out.println("Subtest empty iterator");
freq_it = new FrequencyIterator<Integer>(new int[]{}, new Integer[]{});
ok(! freq_it.hasNext(), "[if empty] should return false (end)");
try {
freq_it.next();
fail("should throw exception NoSuchElementException, but does not throw!");
} catch(NoSuchElementException e){
pass("should throw exception NoSuchElementException! yay!");
} catch(Exception e){
fail("should throw exception NoSuchElementException, but throw " + e);
}
System.out.println("Subtest 1x1 iterator");
freq_it = new FrequencyIterator<Integer>(new int[]{1}, new Integer[]{1});
ok(freq_it.hasNext(), "should return true");
is(freq_it.next(), 1, "should return 1");
ok(!freq_it.hasNext(), "should return false (end)");
try {
freq_it.next();
fail("should throw exception NoSuchElementException, but does not throw!");
} catch(NoSuchElementException e){
pass("should throw exception NoSuchElementException! yay!");
} catch(Exception e){
fail("should throw exception NoSuchElementException, but throw " + e);
}
}
public static void pass (String msg) {
System.out.println("\tTest '" + msg + "' OK");
}
public static void fail (String msg) {
System.out.println("\tTest '" + msg + "' NOK!!!!!!!");
}
public static void is(Object o1, Object o2, String msg){
ok( o1 != null && o1.equals(o2), msg + " [ '"+o1+"' should be equals to '"+o2+"' ]" );
}
public static void ok(boolean b, String msg) {
if(b){
pass(msg);
} else {
fail(msg);
}
}
}
bash$ javac -Xlint:unchecked -source 1.7 FrequencyIterator.java
bash$ java -ea -cp . FrequencyIterator
Subtest normal case, with valid numbers
Test 'should has next' OK
Test 'should return 4 [ '4' should be equals to '4' ]' OK
Test 'should has next' OK
Test 'should return 5 [ '5' should be equals to '5' ]' OK
Test 'should has next' OK
Test 'should return 5 again [ '5' should be equals to '5' ]' OK
Test 'should return false (end)' OK
Test 'should throw exception NoSuchElementException! yay!' OK
Subtest should throw if size of arrays are different
Test 'should throw exception IllegalArgumentException! yay!java.lang.IllegalArgumentException: size of frequencies and values should be equal' OK
Subtest should throw if frequencies has negative numbers
Test 'should throw exception IllegalArgumentException! yay!java.lang.IllegalArgumentException: frequencies should be an array of positive integers or 0' OK
Subtest empty iterator
Test '[if empty] should return false (end)' OK
Subtest 1x1 iterator
Test 'should return true' OK
Test 'should return 1 [ '1' should be equals to '1' ]' OK
Test 'should return false (end)' OK
Test 'should throw exception NoSuchElementException! yay!' OK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment