Substitute value in HashMap at runtime

Discussion in 'Java' started by mike, Oct 13, 2011.

  1. mike

    mike Guest

    Hi,

    If I create a HashMap with something like:

    static Map<String,String> map = new
    HashMap<String,String>("variable",MyPreferences.getVariableValue());

    If I do it like this I guess that MyPreferences.getVariableValue()
    will not be substituted but be the "plain" string.

    How can I make my MyPreferences.getVariableValue() be evaluated at
    runtime? Any example?

    br,

    //mike
    mike, Oct 13, 2011
    #1
    1. Advertising

  2. mike

    Lew Guest

    mike wrote:
    > If I create a HashMap with something like:
    >
    > static Map<String,String> map = new
    > HashMap<String,String>("variable",MyPreferences.getVariableValue());
    >
    > If I do it like this I guess that MyPreferences.getVariableValue()
    > will not be substituted but be the "plain" string.


    Nope. If you do it like that your code will fail to compile (assuming you're referring to 'java.util.HashMap').
    <http://download.oracle.com/javase/7/docs/api/java/util/HashMap.html>

    Put together a Simple Self-Contained Compilable Example (SSCCE) per
    http://sscce.org/

    Seriously. Do it.

    Even if you use a correct constructor, if 'MyPreferences.getVariableValue()' is not of type 'String' you have a problem:

    public class Foo
    {
    static Map<String,String> map = new HashMap<>();
    static
    {
    map.put( "variable", MyPreferences.getVariableValue() );
    }
    }

    The type of the entry must match the type of the target.

    BTW, I assume that 'getVariableValue()' is a static member of 'MyPreferences', given that you named the latter as a type and not a variable.

    > How can I make my MyPreferences.getVariableValue() be evaluated at
    > runtime? Any example?


    Use the expression 'MyPreferences.getVariableValue()'.

    Let's see that SSCCE in your next post, otherwise there's not much point in continuing, is there? We need full data to understand what you aim to accomplish, and you need full data for any answer to make any sense.

    SSCCE.

    http://sscce.org/

    --
    Lew
    Lew, Oct 13, 2011
    #2
    1. Advertising

  3. On Oct 13, 2:18 pm, mike <> wrote:
    > If I create a HashMap with something like:
    >
    > static Map<String,String> map = new
    > HashMap<String,String>("variable",MyPreferences.getVariableValue());
    >
    > If I do it like this I guess that MyPreferences.getVariableValue()
    > will not be substituted but be the "plain" string.
    >
    > How can I make my MyPreferences.getVariableValue() be evaluated at
    > runtime? Any example?


    One possible way is to change your Map to Map<String,
    Callable<String>> and invoke call() at runtime.

    http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Callable.html

    Of course you then need to provide a proper implementation. :)

    Btw, does your Map contain more entries? If not, it's completely
    superfluous.

    If you define the Map as static you also need to be aware of
    concurrency issues if your application will ever access this from
    multiple threads.

    Cheers

    robert
    Robert Klemme, Oct 13, 2011
    #3
  4. mike

    Lew Guest

    Robert Klemme wrote:
    > mike wrote:
    >> If I create a HashMap with something like:
    >>
    >> static Map<String,String> map = new
    >> HashMap<String,String>("variable",MyPreferences.getVariableValue());
    >>
    >> If I do it like this I guess that MyPreferences.getVariableValue()
    >> will not be substituted but be the "plain" string.
    >>
    >> How can I make my MyPreferences.getVariableValue() be evaluated at
    >> runtime? Any example?

    >
    > One possible way is to change your Map to Map<String,
    > Callable<String>> and invoke call() at runtime.
    >
    > http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Callable.html
    >
    > Of course you then need to provide a proper implementation. :)
    >
    > Btw, does your Map contain more entries? If not, it's completely
    > superfluous.
    >
    > If you define the Map as static you also need to be aware of
    > concurrency issues if your application will ever access this from
    > multiple threads.


    It doesn't even have to be multiple threads. Multiple instances in the same thread can clobber a static structure if careless. They just take turns messing each other up.

    --
    Lew
    Lew, Oct 13, 2011
    #4
  5. mike

    mike Guest

    On Oct 13, 7:12 pm, Lew <> wrote:
    > Robert Klemme wrote:
    > > mike wrote:
    > >> If I create a HashMap with something like:

    >
    > >> static Map<String,String> map = new
    > >> HashMap<String,String>("variable",MyPreferences.getVariableValue());

    >
    > >> If I do it like this I guess that MyPreferences.getVariableValue()
    > >> will not be substituted but be the "plain" string.

    >
    > >> How can I make my MyPreferences.getVariableValue() be evaluated at
    > >> runtime? Any example?

    >
    > > One possible way is to change your Map to Map<String,
    > > Callable<String>> and invoke call() at runtime.

    >
    > >http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Cal...

    >
    > > Of course you then need to provide a proper implementation. :)

    >
    > > Btw, does your Map contain more entries?  If not, it's completely
    > > superfluous.

    >
    > > If you define the Map as static you also need to be aware of
    > > concurrency issues if your application will ever access this from
    > > multiple threads.

    >
    > It doesn't even have to be multiple threads.  Multiple instances in thesame thread can clobber a static structure if careless.  They just take turns messing each other up.
    >
    > --
    > Lew


    Hi,

    I put together a more complete example ( however it is not so small).
    Here is the class ( see below).
    The map will contain more values. Maybe I can do it final since it
    will not change when values are loaded.

    I will use the output from runtime value of
    test.TextHelp.getCurrentActivity().

    When I run the code below I get:

    java.lang.NoSuchMethodException: test.TextHelp.getCurrentActivity()()
    at java.lang.Class.getMethod(Class.java:1581)
    at test.TextHelp.getValue(TextHelp.java:70)
    at test.TextHelp.replace(TextHelp.java:47)
    at test.TextHelp.main(TextHelp.java:21)

    Any ideas?

    I am using java 1.5 and cannot go with 1.6 yet.

    Thanks for all your comments.

    //mike

    package test;

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;


    public class TextHelp {

    public String getCurrentActivity(){
    return "my activity name";
    }

    public static void main (String [] args){
    TextHelp th = new TextHelp();
    System.out.println("Output before is: act-{stream}");
    String runtimeText = TextHelp.replace("act-{stream}");
    System.out.println("Output after is: "+runtimeText);
    }

    private static Map<String, String> replacements = new HashMap<String,
    String>();

    static{
    replacements.put("{stream}","test.TextHelp:getCurrentActivity()");
    }

    public static String replace(final String msg) {

    if (msg == null || "".equals(msg) || replacements == null
    || replacements.isEmpty()) {
    return msg;
    }
    StringBuilder regexBuilder = new StringBuilder();
    Iterator<String> it = replacements.keySet().iterator();
    regexBuilder.append(Pattern.quote(it.next()));
    while (it.hasNext()) {
    regexBuilder.append('|').append(Pattern.quote(it.next()));
    }
    Matcher matcher =
    Pattern.compile(regexBuilder.toString()).matcher(msg);
    StringBuffer out = new StringBuffer(msg.length() + (msg.length() /
    10));
    while (matcher.find()) {
    String toBeSubstituted = replacements.get(matcher.group());
    String replacement = getValue(toBeSubstituted);
    matcher.appendReplacement(out, replacement);
    //matcher.appendReplacement(out,
    replacements.get(matcher.group()));
    }
    matcher.appendTail(out);
    System.out.println("OUT "+out);
    return out.toString();
    }



    public static String getValue(String expression) {

    String[] parts = expression.split(":");

    // Obtain the Class instance
    String result = "";
    try {
    // Obtain the Class
    // Obtain the Class instance
    Class cls = Class.forName(parts[0]);

    // Get the method
    Method method = cls.getMethod(parts[1],null);

    // Create the object that we want to invoke the methods on
    TextHelp provider = (TextHelp) cls
    .newInstance();
    // Call the method. Since none of them takes arguments we just
    // pass an empty array as second parameter.
    result = (String)method.invoke(provider, new Object[0]);

    } catch (IllegalArgumentException ex) {
    ex.printStackTrace();

    } catch (InvocationTargetException ex) {
    ex.printStackTrace();

    } catch (IllegalAccessException ex) {
    ex.printStackTrace();

    } catch (ClassNotFoundException ex) {
    ex.printStackTrace();

    } catch (SecurityException ex) {
    ex.printStackTrace();

    } catch (NoSuchMethodException ex) {
    ex.printStackTrace();
    } catch (InstantiationException ex) {
    ex.printStackTrace();
    }
    System.out.println("Result " + ": " + result);
    return result;
    }
    }
    mike, Oct 14, 2011
    #5
  6. mike

    mike Guest

    On Oct 14, 3:36 pm, mike <> wrote:
    > On Oct 13, 7:12 pm, Lew <> wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > Robert Klemme wrote:
    > > > mike wrote:
    > > >> If I create a HashMap with something like:

    >
    > > >> static Map<String,String> map = new
    > > >> HashMap<String,String>("variable",MyPreferences.getVariableValue());

    >
    > > >> If I do it like this I guess that MyPreferences.getVariableValue()
    > > >> will not be substituted but be the "plain" string.

    >
    > > >> How can I make my MyPreferences.getVariableValue() be evaluated at
    > > >> runtime? Any example?

    >
    > > > One possible way is to change your Map to Map<String,
    > > > Callable<String>> and invoke call() at runtime.

    >
    > > >http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Cal....

    >
    > > > Of course you then need to provide a proper implementation. :)

    >
    > > > Btw, does your Map contain more entries?  If not, it's completely
    > > > superfluous.

    >
    > > > If you define the Map as static you also need to be aware of
    > > > concurrency issues if your application will ever access this from
    > > > multiple threads.

    >
    > > It doesn't even have to be multiple threads.  Multiple instances in the same thread can clobber a static structure if careless.  They just take turns messing each other up.

    >
    > > --
    > > Lew

    >
    > Hi,
    >
    > I put together a more complete example ( however it is not so small).
    > Here is the class ( see below).
    > The map will contain more values. Maybe I can do it final since it
    > will not change when values are loaded.
    >
    > I will use the output from runtime value of
    > test.TextHelp.getCurrentActivity().
    >
    > When I run the code below I get:
    >
    > java.lang.NoSuchMethodException: test.TextHelp.getCurrentActivity()()
    >         at java.lang.Class.getMethod(Class.java:1581)
    >         at test.TextHelp.getValue(TextHelp.java:70)
    >         at test.TextHelp.replace(TextHelp.java:47)
    >         at test.TextHelp.main(TextHelp.java:21)
    >
    > Any ideas?
    >
    > I am using java 1.5 and cannot go with 1.6 yet.
    >
    > Thanks for all your comments.
    >
    > //mike
    >
    > package test;
    >
    > import java.lang.reflect.InvocationTargetException;
    > import java.lang.reflect.Method;
    > import java.util.HashMap;
    > import java.util.Iterator;
    > import java.util.Map;
    > import java.util.regex.Matcher;
    > import java.util.regex.Pattern;
    >
    > public class TextHelp {
    >
    >         public String getCurrentActivity(){
    >                 return "my activity name";
    >         }
    >
    >         public static void main (String [] args){
    >                 TextHelp th = new TextHelp();
    >                 System.out.println("Output before is: act-{stream}");
    >                 String runtimeText = TextHelp.replace("act-{stream}");
    >                 System.out.println("Output after is: "+runtimeText);
    >         }
    >
    >         private static Map<String, String> replacements = new HashMap<String,
    > String>();
    >
    >         static{
    >                 replacements.put("{stream}","test.TextHelp:getCurrentActivity()");
    >         }
    >
    >         public static String replace(final String msg) {
    >
    >                 if (msg == null || "".equals(msg) || replacements == null
    >                                 || replacements.isEmpty()) {
    >                         return msg;
    >                 }
    >                 StringBuilder regexBuilder = new StringBuilder();
    >                 Iterator<String> it = replacements.keySet().iterator();
    >                 regexBuilder.append(Pattern.quote(it.next()));
    >                 while (it.hasNext()) {
    >                         regexBuilder.append('|').append(Pattern.quote(it.next()));
    >                 }
    >                 Matcher matcher =
    > Pattern.compile(regexBuilder.toString()).matcher(msg);
    >                 StringBuffer out = new StringBuffer(msg..length() + (msg.length() /
    > 10));
    >                 while (matcher.find()) {
    >                         String toBeSubstituted = replacements.get(matcher.group());
    >                         String replacement = getValue(toBeSubstituted);
    >                         matcher.appendReplacement(out, replacement);
    >                         //matcher.appendReplacement(out,
    > replacements.get(matcher.group()));
    >                 }
    >                 matcher.appendTail(out);
    >                 System.out.println("OUT "+out);
    >                 return out.toString();
    >         }
    >
    >         public static String getValue(String expression) {
    >
    >                 String[] parts = expression.split(":");
    >
    >                 // Obtain the Class instance
    >                 String result = "";
    >                 try {
    >                         // Obtain the Class
    >                         // Obtain the Class instance
    >                         Class cls = Class.forName(parts[0]);
    >
    >                         // Get the method
    >                         Method method = cls.getMethod(parts[1],null);
    >
    >                         // Create the object thatwe want to invoke the methods on
    >                         TextHelp provider = (TextHelp) cls
    >                                         .newInstance();
    >                         // Call the method. Sincenone of them takes arguments we just
    >                         // pass an empty array assecond parameter.
    >                         result = (String)method..invoke(provider, new Object[0]);
    >
    >                 } catch (IllegalArgumentException ex) {
    >                         ex.printStackTrace();
    >
    >                 } catch (InvocationTargetException ex) {
    >                         ex.printStackTrace();
    >
    >                 } catch (IllegalAccessException ex) {
    >                         ex.printStackTrace();
    >
    >                 } catch (ClassNotFoundException ex) {
    >                         ex.printStackTrace();
    >
    >                 } catch (SecurityException ex) {
    >                         ex.printStackTrace();
    >
    >                 } catch (NoSuchMethodException ex) {
    >                         ex.printStackTrace();
    >                 } catch (InstantiationException ex) {
    >                         ex.printStackTrace();
    >                 }
    >                 System.out.println("Result " + ": " + result);
    >                 return result;
    >         }
    >
    >
    >
    >
    >
    >
    >
    > }


    Hi,

    Found the problem :)

    replacements.put("{stream}","test.TextHelp:getCurrentActivity()"); --
    > replacements.put("{stream}","test.TextHelp:getCurrentActivity");
    mike, Oct 14, 2011
    #6
  7. mike

    markspace Guest

    On 10/14/2011 6:54 AM, mike wrote:

    >> Hi,
    >>
    >> I put together a more complete example


    > Hi,
    >
    > Found the problem :)



    Yes, see why we ask for these things? ;)
    markspace, Oct 14, 2011
    #7
  8. mike

    Roedy Green Guest

    On Thu, 13 Oct 2011 05:18:57 -0700 (PDT), mike
    <> wrote, quoted or indirectly quoted
    someone who said :

    >How can I make my MyPreferences.getVariableValue() be evaluated at
    >runtime? Any example?


    What you need to do is create a HashMap( String, Lookup).

    Your Lookup interface has a lookup method that does whatever
    calculations/lookups you want.

    see http://mindprod.com/jgloss/delegate.html

    P.S. your code as is won't compile. There is a HashMap(Map<? extends
    K, ? extends V> m) constructor, but not one you are using.

    The easiest way to fix the problem is to use a separate put method.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    It should not be considered an error when the user starts something
    already started or stops something already stopped. This applies
    to browsers, services, editors... It is inexcusable to
    punish the user by requiring some elaborate sequence to atone,
    e.g. open the task editor, find and kill some processes.
    Roedy Green, Oct 14, 2011
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ken

    Replace value in HashMap?

    Ken, Jul 7, 2004, in forum: Java
    Replies:
    7
    Views:
    48,480
    kk_oop
    Jul 7, 2004
  2. Vince Darley
    Replies:
    4
    Views:
    4,368
    emilchacko
    Mar 2, 2010
  3. sam
    Replies:
    1
    Views:
    650
    Gianni Mariani
    May 1, 2005
  4. Replies:
    7
    Views:
    759
    Pasi Savolainen
    Feb 26, 2006
  5. Rakesh
    Replies:
    10
    Views:
    12,131
    Mike Schilling
    Apr 8, 2008
Loading...

Share This Page