tags:

views:

440

answers:

3

I'm attempting to make a class that will convert ArrayLists of objects into ArrayLists of other objects. i.e.

ArrayList<Foo> convert(ArrayList<Bar> input){
     //conversion logic
}

ArrayList<Bar> convert(ArrayList<Foo> input){
     //conversion logic
}

Unfortunately Java doesn't want to have two functions with the same name and what it believes to be the same inputs and outputs.

I'm attempting to go a different route. Instead of multiple functions with the same name, I want to make one function that accepts an ArrayList, determines which type of object is inside, does the proper conversion, and returns an ArrayList:

ArrayList convert(ArrayList input){
     //conversion logic for Foo

     //conversion logic for Bar
}

Is something like this possible?

+4  A: 

How about an interface:

public class Converter<From, To> {
    List<To> convert(List<From> input);
}

And then have as many implementations as you want. For example:

private static final Converter<Foo, Bar> fooToBarConverter = new Converter<Foo, Bar>() {
    public List<Bar> convert(List<Foo> input) {
        ...
    }
}
Michael Myers
+4  A: 

Try:

public <T, U> ArrayList<U> convert(Class<T> typeIn, ArrayList<T> input){     
    // dispatch on typeIn
}

Or better yet

public <T, U, V extends ArrayList<U>> V convert(Class<T> typeIn, 
Class<V> typeOut, ArrayList<T> input){     
    // dispatch on typeIn
    return typeOut.cast(yourConversionResult);
}

Because you might return ArrayList<Foo> or ArrayList<Bar> within the same method and having the proper cast will help you return them without compiler warnings.

Edit: The return type cast for the second sample wasn't going to work. Tried to fix it

kd304
I'm thinking this might be better than my answer. (By the way, you can add a "public" in there to get the syntax highlighting off of XML mode).
Michael Myers
I'm not familiar with the <T, U> syntax. Could you provide a more verbose example, or perhaps a link?
KevMo
@KevMo: It means the method is generic, even though the containing class might not be.
Michael Myers
Thanks. Not sure about the return type cast though.
kd304
A: 

You are basically describing a "map" in terms of functional programming. Take a list of objects, apply some operation to each object and accumulate the results in another list. There are libraries out there that implement this stuff already, although i haven't looked recently. I know commons collections has this for pre-generics collections.

the gist of the solution is (similar to mmeyers solution):

public interface Function<From,To> {
  public To apply(From);
}

public <From,To> List<To> map(List<From> fromList, Function<From,To> fun)  {
  // call fun.apply() on every element in fromList and return a new result list ...
}
james
You are #18 to misspell my name on SO. Congratulations. ;)
Michael Myers
heh, my bad. :)
james