I expect the TakeIterator to only call the hasNext() method for the delegate a maximum of N times where N is the number of elements to take. If the iterator represents some expensive operations, or an unexhausted infinite stream that has exactly N elements available, the TakeIterator will block waiting for the Nth+1 element only to return N of them.
In short, change the TakeIterator's hasNext function from
return delegate.hasNext() && num > 0;
return num > 0 && delegate.hasNext();