I have a map that is built when an object is called, which provides the caller with variable names as keys and getter/setter pairs as values. This works as expected. My problem is that it builds every time I call it, I was wondering if there is a way to declare it as static and just provide the object that I want to call it on so that I don't build the map every time because Getters and setters do not change at runtime.
I have:
package main; import org.javatuples.Pair; import java.util.Map; import java.util.function.Consumer; import java.util.function.Supplier; public interface MapPackHelperI { public Map<String, Pair<Supplier, Consumer>> getNameToGetterSetterMap(); }
package main; import java.util.List; import java.util.Map; import java.util.HashMap; import org.javatuples.Pair; import java.util.function.Consumer; import java.util.function.Supplier; public class SomeStruct implements MapPackHelperI { private long somelong; private String somestring; private List<Float> somelistfloat; private SomeEnum someenum; public Map<String, Pair<Supplier, Consumer>> getNameToGetterSetterMap() { Map<String, Pair<Supplier, Consumer>> nameToGetterSetterMap = new HashMap<>(); nameToGetterSetterMap.put("somelong", Pair.with( this::getSomelong, (Consumer<Long>)this::setSomelong)); nameToGetterSetterMap.put("somestring", Pair.with( this::getSomestring, (Consumer<String>)this::setSomestring)); nameToGetterSetterMap.put("somelistfloat", Pair.with( this::getSomelistfloat, (Consumer<List<Float>>)this::setSomelistfloat)); nameToGetterSetterMap.put("someenum", Pair.with( this::getSomeenum, (Consumer<SomeEnum>)this::setSomeenum)); return nameToGetterSetterMap; } public long getSomelong() { return this.somelong; } public void setSomelong(long somelong) { this.somelong = somelong; } public String getSomestring() { return this.somestring; } public void setSomestring(String somestring) { this.somestring = somestring; } public List<Float> getSomelistfloat() { return this.somelistfloat; } public void setSomelistfloat(List<Float> somelistfloat) { this.somelistfloat = somelistfloat; } public SomeEnum getSomeenum() { return this.someenum; } public void setSomeenum(SomeEnum someenum) { this.someenum = someenum; } // ... hashcode, toString, and equals, not relevant for the example }
This allows me to do from elsewhere:
public static String serialize(MapPackHelperI objectToSerialize) { Map<String, Pair<Supplier, Consumer>> nameToGetterSetterMap = objectToSerialize.getNameToGetterSetterMap(); for(Entry<String, Pair<Supplier, Consumer>> current : nameToGetterSetterMap.entrySet()) { String name = current.getKey(); Supplier getter = current.getValue().getValue0(); //code that serializes into string with name and getter regardless of the MapPackHelperI I pass in } // return the string representation of the object. I have another method that uses the same map to go the other way with the setter. }
Like I said, this works, but every time I call it I instantiate and populate the map.
Is there a way for SomeStruct
to have a public static Map<String, Pair<Supplier, Consumer>> nameToGetterSetterMap = new HashMap<>();
(or some etc. (effective), so public Map<String, Pairphpcnltphp cnSupplier, Consumer>> getNameToGetterSetterMap()
takes the instantiated parameter as argument SomeStruct
and applies the call only to that specific object.
I tried making a static map and filling it with SomeStruct::getSomelong
etc. but the compiler said I can't do that.
The answer seems so obvious, I must be missing something: cache newly constructed mappings as private member fields.
public class SomeStruct implements MapPackHelperI { private long somelong; private String somestring; private List<Float> somelistfloat; private SomeEnum someenum; private Map<String, Pair<Supplier, Consumer>> map = Map.of( "somelong", Pair.with( this::getSomelong, (Consumer<Long>)this::setSomelong) , "somestring", Pair.with( this::getSomestring, (Consumer<String>)this::setSomestring) , "somelistfloat", Pair.with( this::getSomelistfloat, (Consumer<List<Float>>)this::setSomelistfloat) , "someenum", Pair.with( this::getSomeenum, (Consumer<SomeEnum>)this::setSomeenum) ) ; public Map<String, Pair<Supplier, Consumer>> getNameToGetterSetterMap() { return this.map ; } …
Please note that Map.of
is cannot be modified.
You should be able to set the map
member variable to static
, but unless you are sure you are instantiating SomeStruct
countless times, I think this Micro-optimizations are not worth the trouble.
The above is the detailed content of How to make a static version of a Map that holds an object's getters/setters?. For more information, please follow other related articles on the PHP Chinese website!