varunkr
varunkr

Reputation: 5542

Java: How to have list type take variable arguments

I have a class like this

class Dummy{
    public getData(Info info){
        List<SomeType> list = info.getDataAsPerInfo();

        List<SomeType> result=new List<>();  

        for(SomeType someType: list){
            // extracting data from someType, lets say this data is 
            // resType (it also of SomeType)
            result.add(resType);  
        }
    }

    public static void main(String args[]){
        Info1 info = new Info1();   // Info1 extends Info
        // adding paramters to info
        new Dummy().getData(info);
    }
}

Now the problem is that I have several Info classes like Info1, Info2 ... and there getData method might return different types of list. I can't figure how to achieve this without rewriting the code for each and every Info class( this would involve replacing SomeType with the return type of that class' getdataAsPerInfo function). Is there a way such that I can somehow use SomeType according to the Info type that is passed to the getData function? What would be the best approach in this case? Thanks !!

Upvotes: 0

Views: 82

Answers (3)

Nicktar
Nicktar

Reputation: 5575

Just take a look at the Oracle tutorial for Generics.

You can't only define one specific class as the type for your lists elements but also families of classes or classes implementing a specific interface.

edit to incorporate comments.

When your Info.getDataAsPerInfo() returns Lists of different Objects depending on which InfoX class is used, this would be a use case for a generic interface.

public interface Info<T> {
    List<T> getDataAsPerInfo();
}

with implementations like:

public class Info1 implements Info<SomeType> 

or

public class Info2 implements Info<SomeOtherType>

Then your Dummy-class would look like

class Dummy {
    public getData(Info<T> info) {
        List<T> list = info.getDataAsPerInfo();

        List<T> result=new List<>();  

        for(T someType: list){
            // extracting data from someType, lets say this data is 
            // resType (it also of SomeType)
            result.add(resType);  
        }
    }

    public static void main(String args[]){
        Info1 info = new Info1();   // Info1 extends Info<SomeType>
        // adding paramters to info
        new Dummy().getData(info);
    }
}

Upvotes: 2

C. Donavon
C. Donavon

Reputation: 56

If the info of each class is a different type but either extends or implements a main supertype you can use List< ? extends Type > which would work

You could always use List< ? > which returns any value as the generic, it's basically an unknown object so just have getData return List< ? > and it should work fine, then check they type with "instanceof" or other ways of doing it, this should work for what you're trying to achieve.

Or for the method you're using (it looks like) you can use T settings, here's a snippet of code with what I think you're trying to achieve.

    public <T> List<T> getInfo(T type) {
        // T here would be the type
        return new ArrayList<T>();
    }

Your question is kind of ambiguous so if you could explain more of what you're trying to do then I could help a lot more.

Upvotes: 1

Laksitha Ranasingha
Laksitha Ranasingha

Reputation: 4507

I don't think you need to fiddle with generics here. You are looking for a solution where you could decide the functionality of SomeType in runtime (polymorphically). Have look at this solution.

    private interface SomeType {
        void doAThing();
    }

    private class AnotherType implements SomeType {

        @Override
        public void doAThing() {
            System.out.println("AnotherType.doAThing");
        }
    }

    private class OneMoreType implements SomeType {

        @Override
        public void doAThing() {
            System.out.println("OneMoreType.doAThing");
        }
    }

    private abstract class Info {
        public abstract SomeType getDataAsPerInfo();
    }

    private class Info1 extends Info {

        @Override
        public SomeType getDataAsPerInfo() {
            return new AnotherType();
        }
    }

    private class Info2 extends Info {

        @Override
        public SomeType getDataAsPerInfo() {
            return new OneMoreType();
        }
    }

Now you can return SomeType from Info and specifically implement the functionality in subclasses.

Upvotes: 1

Related Questions