我有一个在调用对象时构建的映射,该映射为调用者提供变量名称作为键和 getter/setter 对作为值。这按预期工作。我的问题是,我每次调用它时都会构建它,我想知道是否有一种方法可以将其声明为静态并仅提供我想要调用它的对象,这样我就不会每次都构建地图因为 getter 和 setter 在运行时不会改变。
我有:
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
}
这允许我从其他地方做:
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.
}
就像我说的,这可行,但每次调用它时我都会实例化并填充地图。
有没有办法让
SomeStruct
拥有 public static Map<String, Pair<Supplier, Consumer>> nameToGetterSetterMap = new HashMap<>();
(或类似的东西),这样 public Map<String, Pair<Supplier, Consumer>> getNameToGetterSetterMap()
将实例化的 SomeStruct
作为参数,并且仅将调用应用于该特定对象。
我尝试做一个静态地图并用
SomeStruct::getSomelong
等填充它,但编译器说我不能这样做。
答案似乎如此明显,我一定错过了一些东西:将新构造的映射缓存为私有成员字段。
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 ;
}
…