views:

280

answers:

4

Hello, I was wondering if it's possible to write a function that accepts multiple generic types as follows:

public int void myfunction(Set<T> a, Set<T> b) {
    return 5;
}

Set<Integer> setA = new HashSet<Integer>();
Set<String> setB = new HashSet<String>();
int result = myfunction(setA, setB);

Will that work? Does the generic in each parameter mean that each parameter must have the same type T that's generic?

Thanks!

+1  A: 

a and b must both be sets of the same type. But nothing prevents you from writing

myfunction(Set<X> a, Set<Y> b)
Dmitry
Thanks for the quick reply!
Jasie
Except that you need to declare the type parameters in the signature as in my answer
oxbow_lakes
You shouldn't accept a wrong answer. @oxbow_lakes was the first one to get it right.
Paul Tomblin
+10  A: 

Yes - it's possible (though not with your method signature) and yes, with your signature the types must be the same.

With the signature you have given, T must be associated to a single type (e.g. String or Integer) at the call-site. You can, however, declare method signatures which take multiple type parameters

public <S, T> void func(Set<S> s, Set<T> t)

Note in the above signature that I have declared the types S and T in the signature itself. These are therefore different to and independent of any generic types associated with the class or interface which contains the function.

public class MyClass<S, T> {
   public        void foo(Set<S> s, Set<T> t); //same type params as on class
   public <U, V> void bar(Set<U> s, Set<V> t); //type params independent of class
}

You might like to take a look at some of the method signatures of the collection classes in the java.util package. Generics is really rather a complicated subject, especially when wildcards (? extends and ? super) are considered. For example, it's often the case that a method which might take a Set<Number> as a parameter should also accept a Set<Integer>. In which case you'd see a signature like this:

public void baz(Set<? extends T> s);

There are plenty of questions already on SO for you to look at on the subject! Not sure what the point of returning an int from the function is, although you could do that if you want!

oxbow_lakes
I don't understand why it's "Yes" to both questions (specifically, why "Yes" to "Will this work?"). The function above (contrived, I know, with the int-return) won't accept the two different types since it expects the same generic type T for both parameters, right?
Jasie
Sorry - I meant "yes it's possible" and "yes, in the signature you defined, the types need to be the same"
oxbow_lakes
I've clarified it now
oxbow_lakes
Ok, thanks for the clarification and your detailed response.
Jasie
+1  A: 

You can declare multiple type variables on a type or method. For example, using type parameters on the method:

<P, Q> int f(Set<P>, Set<Q>) {
  return 0;
}
erickson
+1  A: 

In your function definition you're constraining sets a and b to the same type. You can also write

public <X,Y> void myFunction(Set<X> s1, Set<Y> s2){...}
Steve B.