code: public static <E> SetView<E> difference(final Set<E> set1, final Set<?> set2) {
      checkNotNull(set1, "set1");
      checkNotNull(set2, "set2");
  
      final Predicate<Object> notInSet2 = Predicates.not(Predicates.in(set2));
      return new SetView<E>() {
        @Override
        public UnmodifiableIterator<E> iterator() {
          return Iterators.filter(set1.iterator(), notInSet2);
        }
  
        @Override
        public int size() {
          return Iterators.size(iterator());
        }
  
        @Override
        public boolean isEmpty() {
          return set2.containsAll(set1);
        }
  
        @Override
        public boolean contains(Object element) {
          return set1.contains(element) && !set2.contains(element);
        }
      };
    }
docs: Returns an unmodifiable <b>view</b> of the difference of two sets. The
  returned set contains all elements that are contained by {@code set1} and
  not contained by {@code set2}. {@code set2} may also contain elements not
  present in {@code set1}; these are simply ignored. The iteration order of
  the returned set matches that of {@code set1}.
  
  <p>Results are undefined if {@code set1} and {@code set2} are sets based
  on different equivalence relations (as {@code HashSet}, {@code TreeSet},
  and the keySet of an {@code IdentityHashMap} all are).