Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I map a String to a function in Java?

Currently, I have a bunch of Java classes that implement a Processor interface, meaning they all have a processRequest(String key) method. The idea is that each class has a few (say, <10) member Strings, and each of those maps to a method in that class via the processRequest method, like so:

class FooProcessor implements Processor
{
    String key1 = "abc";
    String key2 = "def";
    String key3 = "ghi";
    // and so on...

    String processRequest(String key)
    {
        String toReturn = null;
        if (key1.equals(key)) toReturn = method1();
        else if (key2.equals(key)) toReturn = method2();
        else if (key3.equals(key)) toReturn = method3();
        // and so on...

        return toReturn;
    }

    String method1() { // do stuff }
    String method2() { // do other stuff }
    String method3() { // do other other stuff }
    // and so on...
}

You get the idea.

This was working fine for me, but now I need a runtime-accessible mapping from key to function; not every function actually returns a String (some return void) and I need to dynamically access the return type (using reflection) of each function in each class that there's a key for. I already have a manager that knows about all the keys, but not the mapping from key to function.

My first instinct was to replace this mapping using if-else statements with a Map<String, Function>, like I could do in Javascript. But, Java doesn't support first-class functions so I'm out of luck there. I could probably dig up a third-party library that lets me work with first-class functions, but I haven't seen any yet, and I doubt that I need an entire new library.

I also thought of putting these String keys into an array and using reflection to invoke the methods by name, but I see two downsides to this method:

  • My keys would have to be named the same as the method - or be named in a particular, consistent way so that it's easy to map them to the method name.
  • This seems WAY slower than the if-else statements I have right now. Efficiency is something of a concern because these methods will tend to get called pretty frequently, and I want to minimize unnecessary overhead.

TL; DR: I'm looking for a clean, minimal-overhead way to map a String to some sort of a Function object that I can invoke and call (something like) getReturnType() on. I don't especially mind using a 3rd-party library if it really fits my needs. I also don't mind using reflection, though I would strongly prefer to avoid using reflection every single time I do a method lookup - maybe using some caching strategy that combines the Map with reflection.

Thoughts on a good way to get what I want? Cheers!

like image 861
Matt Ball Avatar asked Apr 30 '10 15:04

Matt Ball


People also ask

Can I use map with strings?

Using map() with a string as an iteratorWe can also make use of map() on a string.

Can I convert a string to map in Java?

We can also convert an array of String to a HashMap. Suppose we have a string array of the student name and an array of roll numbers, and we want to convert it to HashMap so the roll number becomes the key of the HashMap and the name becomes the value of the HashMap. Note: Both the arrays should be the same size.

What is map <? ?> In Java?

A Map is an object that maps keys to values. A map cannot contain duplicate keys: Each key can map to at most one value. It models the mathematical function abstraction.


1 Answers

This example uses an enum of named functions and an abstract FunctionAdapter to invoke functions with a variable number of homogeneous parameters without reflection. The lookup() function simply uses Enum.valueOf, but a Map might be worth it for a large number of functions.

like image 129
trashgod Avatar answered Oct 07 '22 07:10

trashgod