Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java how to store getters in map

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?

like image 298
userit1985 Avatar asked Oct 18 '25 22:10

userit1985


2 Answers

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>.

like image 156
Eran Avatar answered Oct 20 '25 12:10

Eran


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.

like image 33
Hoopje Avatar answered Oct 20 '25 12:10

Hoopje



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!