Denis Saidov
Denis Saidov

Reputation: 93

Dynamically return an ArrayList

I'm struggling with a method dynamically returning an

ArrayList<Player>

Here's what I have:

Fantasy class

public class Fantasy {
   Squad team;
   ArrayList<Player> substitutes = team.getList(substitutes);
}

Squad class

public class Squad {
   ArrayList<Player> substitutes;
   // Some code adding stuff into the ArrayList

   public ArrayList<Player> getList(String list) {
      return ArrayList<Player> list; << PROBLEM
   }
}

I want to have a method getList() through which I can pass a name of an ArrayList, which will check if an ArratList with the same name exists, and if yes, return it back as an ArrayList.

The problem is that I have no idea how to check if there's an ArrayList named the same as the String list I'm passing.

POSSIBLE SOLUTION:

Map<String, ArrayList<Player>> arrayLists = new HashMap<String, ArrayList<Player>>(){{
    put("goalKeepers", goalKeepers);
    put("defenders", defenders);
    put("midFielders", midFielders);
    put("strikers", strikers);
    put("substitutes", substitutes);
}};

and

public ArrayList<Player> getList(String list) {
    return arrayLists.get(list);
}

BUT, when I call:

ArrayList test = getList("substitute");

or whenever I use getList(); I get the following error:

Cannot make a static reference to the non-static method getList(String) from the type Squad

Upvotes: 0

Views: 478

Answers (5)

Tobi Nonymous
Tobi Nonymous

Reputation: 611

What you want to do can be achieved by using Reflections. The implementation would look something like this:

public List<Player> getList(String list) {
    try {
        Field field = this.getClass().getDeclaredField(list);
        return (List<Player>) field.get(this);
    } catch (IllegalAccessException e) {
         // do something sensible
    }
}

This checks your current object for a member field with the name you provided and returns the value of the field. Generally you should avoid Reflections until you really know what you are doing and have no other option.

In your case you seem to have the problem that Java is a compiled language and does not provide some features that you can use in common script languages. One of the main features of a compiled language is that you can depend the language to find the references for you. Using reflections to try to match a String to a field, you throw away this benefit. Therefore the better solution would probably be to go with a Map like the other answers suggest.

One last thing: following the SOLID principles for OOP you should depend on the List interface rather than the ArrayList implementation in your type declarations. (The 'D' in SOLID)

Upvotes: 0

Mohsin AR
Mohsin AR

Reputation: 3108

You could use

Map<String,ArrayList<>> myMap = new HashMap<String,ArrayList<>>();

Here you can find which arraylist available on String key.

Upvotes: 0

Mick Mnemonic
Mick Mnemonic

Reputation: 7956

Instead of storing the lists of substitutes in distinct instance variables, you should have one field that stores the mapping of team names into the corresponding list of players:

public class Squad {

   Map<String, List<Player>> substitutes = new HashMap<>();

   // add the player lists into the map

   /*
   * Returns the list of players for the given team name,
   * can be {@code null} if no player list has been stored
   * with the team name.
   */
   public List<Player> getList(String teamName) {
      return substitutes.get(teamName);
   }
}

Upvotes: 1

stegzzz
stegzzz

Reputation: 407

If your Squad maintains a

HashMap<String, ArrayList<Player>>

you can use that to return the ArrayList given a String key.

Upvotes: 0

Maljam
Maljam

Reputation: 6274

There no way implemented in the Java language to use the names you assign to variables/methods in the logic or flow of the code.

You would have to implement it yourself, for example:

public ArrayList getList(String name) {
    if(name.equals("substitutes") && substitutes != null) {
        return substitutes;
    }

    else {
        //handle error as you like
    }
}  

And you can add else if statements for other lists or objects that you want to access.

Upvotes: 0

Related Questions