Java 使用泛型创建分层对象的分层存储
我正在开发一个解析/验证基础设施来处理对象 在我的申请中。解析过程非常快,而且 验证过程非常缓慢,通常不会失败。解析 流程生成对象Java 使用泛型创建分层对象的分层存储,java,generics,collections,Java,Generics,Collections,我正在开发一个解析/验证基础设施来处理对象 在我的申请中。解析过程非常快,而且 验证过程非常缓慢,通常不会失败。解析 流程生成对象Foo和验证流程 另外生成ExtendedFoo 公共类Foo{ 私人长id; } 公共类ExtendedFoo扩展Foo{ 私有布尔值是有效的; } 解析过程的输出存储在这样的类中(除了Foo),还有其他类型的对象: 公共类存储{ 私有映射foos=newhashmap(); 私有映射栏=新的HashMap(); 公共映射getFoos(){return foos
Foo
和验证流程
另外生成ExtendedFoo
公共类Foo{
私人长id;
}
公共类ExtendedFoo扩展Foo{
私有布尔值是有效的;
}
解析过程的输出存储在这样的类中(除了Foo
),还有其他类型的对象:
公共类存储{
私有映射foos=newhashmap();
私有映射栏=新的HashMap();
公共映射getFoos(){return foos;}
公共映射getBars(){return bars;}
}
而该存储是该应用程序所需的最低基本信息
应用程序
当我想运行附加验证时,我想使用
以下结构:
公共类扩展存储扩展存储{
公共地图getFoos(){
return(Map)super.getFoos();
}
//由于没有验证,所以未扩展条
}
但是“未经检查的演员阵容”让我觉得有更好的方法
解决这个问题
解决这个问题的java通用“惯用”方法是什么?通用分层存储方法的一些想法包括:
public static class TypeStore<T>
{
private final Map<String, T> validData;
private final Map<String, T> parsedData;
private final Predicate<? super T> isValid;
public TypeStore(Map<String, T> parsedData, Predicate<? super T> isValid)
{
this.validData = new HashMap<>();
this.parsedData = parsedData;
this.isValid = isValid;
}
public Optional<T> getValue(String key) { return Optional.ofNullable(parsedData.get(key)); }
public Optional<T> getValidValue(String key) { return Optional.ofNullable(validData.computeIfAbsent(key, k -> getValue(k).filter(isValid).orElse(null))); }
}
公共静态类类型存储
{
私人最终地图validData;
私人最终地图数据;
私有终结谓词
“此存储是应用程序所需的最低基本信息…”
这表明需要一个统一的抽象概念,如
public interface Storable< MBI > {
MBI getMinimumBasicInformation( );
}
以及类型安全实现(零未检查的警告)
公共类扩展存储,MBI>扩展存储{
公共扩展存储区(){super();}
公共扩展存储(Map存储){super(存储);}
@凌驾
公共映射getStored(){
返回super.getStored();
}
}
然后是一个示例,它存储了一个对象()
公共类Foo实现可存储{
保护长id;
@凌驾
public Long getMinimumBasicInformation(){返回this.id;}
}
我很可能会使用流来处理这些IRL。但由于这只是一个简单的实验,仅仅意味着四处走动
…
StorefooStore=newextendedstore<>(新HashMap<>(of(“Foo”,newextendedfoo(1L,true),“Foo”,newextendedfoo(2L,true),“Foo”,newextendedfoo(3L,true));
Mapfoos=fooStore.getStored();
fooStore.store(“fuBar”,新扩展的foo(4L,true));
StorebarStore=newextendedstore<>();
MapBar=barStore.getStored();
store(“bar”,新扩展的bar(“bar”,true));
…
不是答案,但是…如果使用Map
你会非常痛苦,因为你不能使用此类型向映射添加任何内容。只需使用Map
或引入一个类型参数。如果不了解你的代码库,我可能会编写一个抽象方法validate()
用于返回具体的ExtendedFoo
实例的Foo
(此时,我不再扩展Foo
,而是使ExtendedFoo
更像一个带有完全封装字段的响应类型对象),它可以返回一个急切缓存的值,也可以动态地延迟验证。我可能根本不会使用映射,如果可能包含的值提前知道,并且您没有使用直接用户输入字符串,我会使用一些自定义对象和字段(糟糕!)当您说:“//bar没有扩展,因为没有验证”
”,这是否意味着ExtendedStore
将只与ExtendedFoos
一起工作?“…(除了Foo
之外还有其他类型的对象)…“-这是否意味着每次在应用程序中引入新类型的对象时,您都计划为这些新类型中的每一个实现另一个Store.getXXX()
?缺少一些相关的东西。例如,当您有一个声明,如private-Map-foos=new-HashMap();
,如何填充此映射?“…可以将多个类型存储添加到配置类…”-这是否意味着每次将新类型的对象引入应用程序时,您都计划实现另一个类型存储(新HashMap()…
对于这些新类型中的每一个?通常使用AppConfig示例是因为原始问题在“Store”类中使用了多个映射。TypeStore寻求提供对底层类型(例如:已验证和未验证视图)的差异访问,其中一个视图的计算成本可能很高(已验证视图).一般来说,可以在需要的地方创建和使用TypeStore,但有时在公共位置拥有配置数据会更好。
public interface Storable< MBI > {
MBI getMinimumBasicInformation( );
}
public class Store< F extends Storable< MBI >, MBI > {
protected Map< String, F > stored;
…
public Map< String, F > getStored( ) { return stored; }
public void store( String key, F storable ){ this.stored.put( key, storable); }
}
public class ExtendedStore< F extends Storable< MBI >, MBI > extends Store< F, MBI > {
public ExtendedStore( ) { super( ) ; }
public ExtendedStore( Map< String, F > stored ) { super( stored ); }
@Override
public Map< String, F > getStored( ) {
return super.getStored( );
}
}
public class Foo implements Storable< Long > {
protected Long id;
@Override
public Long getMinimumBasicInformation( ) { return this.id; }
}
…
Store< Foo, Long > fooStore = new ExtendedStore< >( new HashMap< > ( of( "foo", new ExtendedFoo( 1L, true ) , "FOO", new ExtendedFoo( 2L, true ), "Foo", new ExtendedFoo( 3L, true ) ) ) );
Map< String, Foo > foos = fooStore.getStored( );
fooStore.store( "fuBar", new ExtendedFoo( 4L, true ) );
Store< Bar, String > barStore = new ExtendedStore< >( );
Map< String, Bar > bars = barStore.getStored( );
barStore.store( "bar", new ExtendedBar( "bar", true ) );
…