0

I have a list of keys and corresponding values with about 150 entries. I have a method that will access it multiple times per session, but will never edit it. It will remained unchanged from session to session. I figure because I want to quickly access the values, I would use a hashmap, but I am not sure how to store it for the long term. What the best way of storing it, and then accessing it at the beginning of my program. Thanks!

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
alex
  • 25
  • 2
  • 7
  • Create a singleton class holds value shared across multiple session, act as internal cache.' – Subhrajyoti Majumder Jun 14 '16 at 18:50
  • `redis` is the most common way to go. If you're expecting to scale to store thousands of such key-value pairs, redis would perform real good. Else, if it's constant 150, store it as a json file and parse it when your program boots up. – venkatKA Jun 14 '16 at 18:51
  • Why can't you keep in in-memory? is it the size (or) any other issues? – K139 Jun 14 '16 at 18:56
  • If you want to consider the `public static final` solution, @alex, you can look at http://www.javapractices.com/topic/TopicAction.do?Id=2. – DavidS Jun 14 '16 at 19:09
  • I suppose I could, I just figured since I will never need to change the data, I could avoid 150 .put() calls each time my program starts up, by only creating it once and then continuously accessing it. – alex Jun 14 '16 at 19:09
  • I understand your concern, but know that for the most part there is no faster way to store and retrieve data than in a HashMap. It is for most applications blazingly fast: for 150 entries my ballpark estimate is 1 millisecond. – DavidS Jun 14 '16 at 19:23

3 Answers3

1

Never never? In that case, you should consider building a properties (or JSON, etc) file into the jar of your program. You can then use

new Properties(getClass().getResourceAsStream());

from any class at the same package level as the properties file to get the set of key-value pairs.

If in fact it may change occasionally, you might want to think about some sort of external data store as I see has already been mentioned in comments responding to your question.

DVA
  • 331
  • 2
  • 13
  • yes, never never. how would I go about building it into a jar file? – alex Jun 14 '16 at 19:01
  • The specifics depend on what kind of build tool you're using (something like ant or maven? Just `javac` and `jar`?) but it probably boils down to putting it in the same directory the class files go into before you build the jar.I'm used to maven, and generally under /src/main it will expect a /resources alongside /java which then has a parallel package structure. – DVA Jun 14 '16 at 19:04
  • hey sorry. I am pretty new to java, so I'm not fully getting this. I believe I know how to add the jar, but I am not sure where to type the data to get the jar. would I create an object that contains it and then save it or something like that? – alex Jun 14 '16 at 19:06
  • 1
    If it's actually _never_ going to change, he may as well just store it in a static initialization class: `public static final`. If we assume it's _never_ going to change, then there's no reason to make it easy to change. – DavidS Jun 14 '16 at 19:08
  • That's a reasonable point and saves me the trouble of explaining the process of building files into jars with the no-newlines restriction that comments impose, so I endorse that instead. – DVA Jun 14 '16 at 19:09
  • If I were to take this route, wouldn't I have 150 .put() calls each time I start my program to get all the data into a hashmap (or any other data structure)? – alex Jun 14 '16 at 19:11
  • He's suggesting a separate constant (`final`) value for each of those. So zero put() calls, 150 constants. But a properties file is going to require you to type out 150 key/value pairs into the file even though loading it into a Properties object in Java is a single line, so either way you have to type the things. – DVA Jun 14 '16 at 19:13
  • Also, maybe you're thinking of program start-up time? In which case I assure you that 150 calls to put() in a hash map is negligible time; same with 150 constants set to values. – DVA Jun 14 '16 at 19:16
  • I was in fact thinking of start-up time. Thank you everyone for your help! – alex Jun 14 '16 at 19:27
  • @DavidS I guess you should post that as an answer so Alex can Accept it and close out the question? – DVA Jun 14 '16 at 19:29
1

If it's actually never going to change, you may as well just store it in a static initialization class: public static final. If we assume it's never going to change, then there's no reason to make it easy to change through other techniques such as loading from a file or a database.

It's up to you whether you store it as a HashMap with 150 entries or a 150 fields in a class. I think it depends on how you want to access the data. If you store it as a HashMap, then you'll likely be accessing the values on a String key, e.g. Constants.getData("max.search.results"). If you store it as 150 fields then just access the fields directly, e.g. Constants.MAX_SEARCH_RESULTS.

As for performance, with 150 entries you have nothing to worry about unless your data is large. People routinely use HashMaps for thousands or millions of entries.

As for when it will be initialized, static fields in Java are initialized only once when the application starts. For 150 entries this should take less than a millisecond (ballpark estimate).

See also

Community
  • 1
  • 1
DavidS
  • 5,022
  • 2
  • 28
  • 55
0

It seems like you could hard-code it, e.g. with a map String -> String:

  public final class CONST
  {
    public static final Map<String, String> DATA;

    static
    {
      final Map<String, String> data = new HashMap<>(200);

      data.put("key001", "value001");
      // ...
      data.put("key150", "value150");

      DATA = Collections.unmodifiableMap(data);
    }
  }

This creates the hash table at the time when the class is loaded. If you want to avoid this for some reason you could also use the initialization-on-demand holder idiom

aventurin
  • 2,056
  • 4
  • 26
  • 30