Access a HashMap from a separate jar - java

So I have this code in JarFile1.jar:
public static HashMap<String, Double[]> myHashMap = new HashMap<String, Double[]>();
How would I access that variable in a separate JarFile2.jar using import?

Put getter and setter to that var in jar1File:
class MyClass {
public HashMap<String, Double[]> getMyHashMap() {
return myHashMap;
}
public void setMyHashMap(HashMap<String, Double[]> myHashMap) {
this.myHashMap = myHashMap;
}
}
Once you are in jarFile2 just you the Class name, Because this is static member.
class MyClassJar2 {
public MyClassJar2() {
MyClass.getMyHashMap();
}
}
So when you will import you can access that var
Hope that help :)

Firstly, that doesn't sound like a good practice at all. It's not a good idea to allow access to an atribute of an object like a Map (you could clutter the data easily and without noticing).
If you want to access data from another class, you could implement a public method like public double[] getData(String key) and importing it in the other jar. Also, note that you need to add the first jar to the classpath while executing the second one.

Related

Better way to initialize Map in constructor in Java

I am trying to initialize a Map to zeros in a class. I am doing that in this way:
public class A{
private final Map<String,Integer> myMap;
public A(){
this.myMap = new HashMap<String,Integer>() {
{
put("a",0);
put("b",0);
}
};
}
}
My question: Is this a good implementation? Is there anything wrong with this? Or is there any better way to implement this?
What Rod_Algonquin meant was:
public class A {
private final Map<String,Integer> myMap;
public A() {
this.myMap = new HashMap<String,Integer>();
this.myMap.put("a",0);
this.myMap.put("b",0);
}
}
Following up on Luiggi Mendoza's comment, since the Map is declared final, you might have meant for the map to be unmodifiable, but final does not assure that. This will:
public class A {
private final Map<String,Integer> myMap;
public A() {
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("a",0);
map.put("b",0);
this.myMap = Collections.unmodifiableMap(map);
}
}
A better way would be to simply put the values in after you've initialized the map:
myMap = new HashMap<>();
myMap.put("a",0);
myMap.put("b",0);
What your current version is doing is that it's using an instance initializer block (a.k.a. double brace initialization), which creates an unnecessary anonymous class in the background. There is no real benefit in doing so here. On the contrary, it will likely cause a small performance hit.
If your real goal is the creation of an immutable Map, I highly recommend using Guava's ImmutableMap.Builder

Unit testing a print method

How to create a class that add some stuff to a map and display it.
I was wondering about the best interface considering that all the code usually need to be covered with unit tests and it's a problem to test a method that display data.
This was my first thought:
class MyFirstProgram {
private Map<String, String> map = new HashMap<String,String>();
public int insertData(...) {...}
public void displayData(...) {...}
}
...but it's not possible to test anything about the retrieval and there is this display method... so I thougt this:
class MyFirstProgram {
private Map<String, String> map = new HashMap<String,String>();
public int insertData(...) {...}
private Map<String, String> retrieveData(...) {...}
public int displayData(...) {...call ; return status}
}
In this it's possible to test the private method with reflection but there is still this display method...
Any idea about the design?
The pragmatic way is to allow access to the Map (via a default/package access method with a comment // for unit tests, and access that. Actually, even better, name the method forUnitTestGetMap() to make it extra clear and avoid confusion with the standard getXXX naming convention. I'm usually fine with just calling toString() on the Map and comparing to what it should be, YMMV. If your insertData() is just calling standard methods on HashMap (e.g. put()) there isn't that much you can and should test, as most of the code is Java library code.
Alternatively, in the displayData() method, does it create an alternative representation of the Data? Such as XML, JSON, maybe a JPanel? If so, look at that to see that the contents of the Data are correct. Obviously XML is much easier than a JPanel for that, but you can still do something like checking that the JPanel has 3 children and the first is a Button named "OK"...
You can try creating getter and setter for the Map variable.
class MyFirstProgram {
private Map<String, String> map = new HashMap<String,String>();
public setMap(Map data) {...}
public Map getMap(...) {...}
}
And then wherever you want to print the map value use getMap method.
If you don't want to use the setters and getters we can have any method which takes a Map as input and print it.
public void PrintMap(Map data){print(data)}

Static Cache - Two "Instances"

I have an application where I need two static caches, once short-term and one long-term.
So I have an abstract class that looks something like this. My thought was that I would create two classes that inherit from this abstract class, thereby attaining my two static classes.
However, it occurs to me that I am creating 3 objects when I might be able to get by with one. But I am at a loss in how to do so. Do I want some sort of factory class?
Can someone suggest an appropriate pattern here?
public abstract class myCache {
static Map<String, Object> ObjectCache = new ConcurrentHashMap<String, Object>();
public void put(String Key, T cmsObject) {
//
}
public xxx static get(String objectKey, Class<T> type) {
//
}
}
Your design is flawed:
A cache is a cache - let the caching class take care of caching... only
Unless the number of objects is large (1000's), don't let the "number of objects created" influence your design
Only the user of your cache class needs to know or care what how the cache is being used
Thus:
public class MyClass {
private static MyCache shortTermCache = new MyCache();
private static MyCache longTermCache = new MyCache();
}
You may consider passing a time-to-live parameter into your cache class constructor to let it manage purging after a certain time.
public abstract class myCache {
static ConcurrentMap<Class<?>,Map<String, Object>> ObjectCache = new ConcurrentHashMap<Class<?>,Map<String, Object>>();
{
ObjectCache.putIfAbsent(getClass(),new ConcurrentHashMap<String,Object>());
}
public void put(String Key, Object cmsObject) {
ObjectCache.get(this.getClass()).put(key,cmsObject);
}
public Object get(String objectKey) {
return ObjectCache.get(this.getClass()).get(key);
}
}

Invoke dynamic java method with out reflection

I have data type which contains 100 properties and 100 getter methods (getproperty1....getproperty100).
I get an input from the user like
Property1
Property2
.
.
Property100
How can I invoke in a quick way the method in this logic
For property1 I need to invoke getproperty1
For propertyI I need to invoke getpropertyI
How can I do this with out using if else, or switch statement or reflection in an efficient way.
Thanks
Your best bet is probably going to be an array or hashmap of some type, and access it by index/key:
public class DataType {
private Map<String, DataProperty> data = new HashMap<String, DataProperty>();
public DataProperty getProperty(String key) {
return data.get(key);
}
public void setProperty(String key, DataProperty value) {
data.put(key, value);
}
}
Although, 100 properties seems like a lot... see if you should break it up or otherwise re-organize it.
You could refactor the class to be a Map. If you have a large number of objects like that it seems more along the lines of a map than an object.
Map<String, Object>
1. If you need to invoke multiple methods I would suggest using the Strategy design pattern. In it's simplest form you could try
public interface Command<T> {
public T getProperty();
}
and then create as many implementations as necessary.
2. If you are only interested in the return type and not the actual invokation the Map<String, T> would be a better alternative.
3. If you want to pass around the information in your program a good alternative would be to use the enum approach
public enum Command {
Property1("some value"),
Property2("some other value");
private String str;
public Command(String str) {
this.str = str;
}
public String getVal() {
return str;
}
}
Which can be used like
Command cmd = ...
String value = cmd.getVal();

Getters/setters of a class having a map

What is the best practice in implementing/providing getters/setters for a class containing a map?
The most common implementation I see is:
public class MyClass {
private Map<String, String> myMap;
public getMyMap() { /* Return an unmodifiable map */ }
public setMyMap(Map<String, String> myMap) { ... }
}
Or would it be better to provide an interface like:
public getMyMap() { /* Return a modifiable map */ }
public addToMap(String key, String value) { myMap.put(key, value); }
And why is such method better?
Both have their uses. The methods exposed by a class should be of a proper level of abstraction. For example if the class is a registry of dogs backed by a Map<String, Dog>, then it could provide methods like:
void addDog(String name, Dog dog);
Dog findByName(String name);
If it's say a rule engine that allows clients to specify the entire rule set in one call, then it could expose methods like:
void setRules(Map<String, Rule> rules);
Map<String, Rule> getRules();
In general I would say try not to return the map at all. Have a method that takes the key and returns the value. Taking a map is ok, as long as you copy it, but a method that takes the key/value and puts it into the map would be my preference.
If you must return the map you should return a read-only version or a copy of it. A set method should also copy the map.
It is a bad idea to allow callers to mutate the data inside of a class without the class knowing, passing or holding onto mutable data is a bad idea.
It totally depends on your requirement. This may suffice in most of the cases.
You may not even have a getter method that returns the map. If you use my plug-in, it may help you creating those methods : http://fast-code.sourceforge.net/documentation.htm#create-list-map as eclipse will not help you create the add method.
I would just provide one. Something like...
public Map<String,String> getMyMap()
{
return myMap;
}
and when you want to use it then
myClass.getMyMap().put(key,value);
DISCLAIMER: I did not compile this and test this answer ;)

Categories