4

I would like to call a dynamic getter by a given enum. I want to define it in a static map. But I'm not sure how my object will use the method.

I have the Color enum and the object Library.

public enum Color {
   Red,
   Blue,
   Black,
   Green,
   Pink,
   Purple,
   White;
}

public class Library{
  public List<String> getRed();
  public List<String> getBlue();
  public List<String> getBlack();
  .....
}

I want to have a Map ,so when I will have a new Library object by the Type I will call the correct get. For example :

private static Map<Color, Function<......>, Consumer<....>> colorConsumerMap = new HashMap<>();
static {
    colorConsumerMap.put(Color.Red,  Library::getRed);
    colorConsumerMap.put(Color.Blue,  Library::getBlue);
}


Library lib = new Library();
List<String> redList = colorConsumerMap.get(Color.Red).apply(lib)

But this way it doesn't compile. Any suggestions please?

userit1985
  • 961
  • 1
  • 13
  • 28

3 Answers3

1

It looks like your Map should be declared as:

private static Map<Color, Function<Library,List<String>> colorConsumerMap = new HashMap<>()

since your getters return List<String>.

Eran
  • 387,369
  • 54
  • 702
  • 768
1

Hi please find the below code for the suppliers :-

enum Color {
    Red,
    Blue,
    Black,
    Green,
    Pink,
    Purple,
    White;
}

class Library{
    public Supplier supplier;
      public List<String> getRed(){};   // implement according to need 
      public List<String> getBlue(){};  // implement according to need 
      public List<String> getBlack(){}; // implement according to need 
    private  Map<Color, Supplier<List<String>>> colorConsumerMap = new HashMap<Color, Supplier<List<String>>>();
    static {
        colorConsumerMap.put(Color.Red,  Library::getRed);
        colorConsumerMap.put(Color.Blue,  Library::getBlue);
    }

Here we are using the java 8 supplier.

To get the value from the HashMap please use the code :-

Supplier getMethod  = colorConsumerMap.get(Color.Red);
List<String> values = getMethod.get();
Hasnain Ali Bohra
  • 2,130
  • 2
  • 11
  • 25
  • @Hasnaim Ali Bohra :I get a comilation error : non static method cannot be referenced from a static context – userit1985 Jul 11 '18 at 12:30
1

The Function interface has two type parameters: the input type (Library in your case) and the output type (List<String> in your case). So you have to change the type of your map to Map<Color, Function<Library, List<String>>.

However, consider to put the logic not in a map, but in the enum values themselves. For example:

public enum Color {
    Red(Library::getRed),
    Blue(Library::getBlue);

    private Function<Library, List<String>> getter;

    private Color(Function<Library, List<String>> getter) {
        this.getter = getter;
    }

    public List<String> getFrom(Library library) {
        return getter.apply(library);
    }
}

public class Library{
    public List<String> getRed() { return Collections.singletonList("Red"); }
    public List<String> getBlue() { return Collections.singletonList("Blue"); }
}

Library lib = new Library();
System.out.println(Color.Red.getFrom(lib));
System.out.println(Color.Blue.getFrom(lib));

Or if you don't want to use Java 8 features:

public enum Color {
    Red {
        List<String> getFrom(Library library) {
            return library.getRed();
        }
    },
    Blue {
        List<String> getFrom(Library library) {
            return library.getBlue();
        }
    };

    abstract List<String> getFrom(Library library);
 }

This has the advantage that if you add a new color later, you cannot forget to update the map, because the compiler will complain if you don't.

Hoopje
  • 12,677
  • 8
  • 34
  • 50