0

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

Denis Saidov
  • 93
  • 1
  • 10
  • I'm not fully understanding your question, but wouldn't it make more sense to have a `getSubstitutes()` method that returns the list: `return substitutes;`? – FThompson Feb 27 '16 at 22:09
  • You only have one List in the `Squad` class, so you only have the one possible list to return. Also your statement "check if such method exists" makes no sense in relation to the rest of your question. Perhaps you should look up what the term "method" means in the context of a Java application. In general your question makes no sense as currently stated. – Mark B Feb 27 '16 at 22:09
  • 2
    Where is list coming from? Are you trying to pull it out of any object member by name? That's rarely a good idea, why not use a `Map>` If you need to pair strings to collections of players – Richard Tingle Feb 27 '16 at 22:10
  • @Vulcan I don't want to use getSubstitutes() method, because I have more than 5 ArrayLists, and don't want to have 5 different methods returning each of them. – Denis Saidov Feb 27 '16 at 22:16
  • @MarkB I meant "ArrayList" instead of method. Sorry, typed the wrong words. – Denis Saidov Feb 27 '16 at 22:27
  • in your updated possible answer you need to call team.getList('substitutes') – Tobi Nonymous Feb 27 '16 at 23:14
  • @TobiNonymous That worked. Thank you! – Denis Saidov Feb 27 '16 at 23:24

5 Answers5

1

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);
   }
}
Mick Mnemonic
  • 7,808
  • 2
  • 26
  • 30
  • I've updated my post with what I've tried based on your solution and the error I get. It seems it should work, though. – Denis Saidov Feb 27 '16 at 22:58
  • It seems that you're not doing what I suggested, but instead declaring the `arrayLists` variable using [double brace initialization](http://stackoverflow.com/questions/1958636/what-is-double-brace-initialization-in-java). Just add `substitutes.put()` calls e.g. in the constructor of `Squad`; it will work. – Mick Mnemonic Feb 27 '16 at 23:14
0

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.

Maljam
  • 6,244
  • 3
  • 17
  • 30
0

If your Squad maintains a

HashMap<String, ArrayList<Player>>

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

stegzzz
  • 407
  • 4
  • 9
0

You could use

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

Here you can find which arraylist available on String key.

Mohsin AR
  • 2,998
  • 2
  • 24
  • 36
0

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)

Tobi Nonymous
  • 581
  • 7
  • 14