I will not offer a complete solution (and judging by your efforts, you do not want this), but I will try to explain so that you yourself find it.
First of all, an unrelated note: you specify a specific iteration order. I assume this is normal and I will not touch it.
Your professor has given you a hint about using limited generics. Make it clear why they are needed (see also the textbook here and / or here ). If you were asked to write one method that takes an argument from either of two unknown types, your solution should be to find and take your general superclass - Object .
In generics, the situation is similar - find the most common denominator, only the syntax is a little more complicated. If you should have written a constructor
ZipIterator(Iterator<Object> f, Iterator<Object> s) {...}
and try to initialize
List<Integer> lst1 = new List<>(); List<String> lst2 = new List<>(); new ZipIterator(it1, it2);
you will get a compilation error (read it). This is because List<String> not List<Object> , although a String is Object . The right way to do this is
ZipIterator(Iterator<? extends Object> f, Iterator<? extends Object> s) {...}
where ? extends Object ? extends Object means "any type that extends Object " (this is all because Object ...).
So, you have a constructor, and you will need to make changes to your class in order to adapt it. You do not even need to implement this Iterator<E> , you just keep 2 of those that you are already doing. Finally, the class itself should not have a common type: since its next method should be able to return any type, it always returns Object .
If you have any questions during your future attempts at this problem or if you find that this solution does not meet the requirements for assignment, feel free to leave comments.