Finding the intersection of elements in two sets
Is there another better way to implement those two methods in 1 and 2?


Of course there is.

My advice is to think about the problem as though you were solving the problem without a computer.

Here, I'm going to give you a list of a thousand unsorted integers between 0 and 999999.

Now I'm going to ask you one thousand times whether a particular number I've chosen at random is on the list.

Would you really try to answer every question by reading down the list from top to bottom every time? 

Give some thought as to how you might solve that problem before you read on.

.

.

.

.

.

No, really, think about it.

.

.

.

You probably thought something like 


the first time I go down the list, I could make ten smaller lists:  numbers I've seen from 0-99999, numbers I've seen from 100000-199999, from 200000-299999, and so on.  That will take a thousand steps to make ten buckets of roughly 100 items each.
Then the second time I'm asked the question, I can first figure out what bucket the number might be in. Then I can search that bucket, and I know I will only have around 100 things to check instead of 1000.
And hey, while I'm doing that, I might as well divide that bucket up into ten buckets of roughly ten items each!


Every time you do a search that makes ten more buckets, you make subsequent searches that hit that bucket ten times faster.

All right, that should get you started; can you implement something like this bucketing algorithm in code?

Now, think the same way about intersection. Can you use the same bucketing trick to make intersection vastly faster? Or something similar?  Again, think about how you would solve the problem if I asked you to do it by hand.