inj*_*cto 3 java generics java-8 cqengine
我使用cqengine进行集合索引:
Attribute<UtilizationEntry, LocalDate> startDateAttr = new SimpleAttribute<UtilizationEntry, LocalDate>() {
@Override
public LocalDate getValue(UtilizationEntry object, QueryOptions queryOptions) {
return object.getStartDate();
}
};
IndexedCollection<UtilizationEntry> entries = new ConcurrentIndexedCollection<>();
entries.addIndex(NavigableIndex.onAttribute(startDateAttr)); // compilation error in this line
Run Code Online (Sandbox Code Playgroud)
此代码未编译,因为:
Error:(61, 70) java: no suitable method found for onAttribute(com.googlecode.cqengine.attribute.Attribute<entities.UtilizationEntry,java.time.LocalDate>)
method com.googlecode.cqengine.index.navigable.NavigableIndex.<A,O>onAttribute(com.googlecode.cqengine.attribute.Attribute<O,A>) is not applicable
(inferred type does not conform to equality constraint(s)
inferred: java.time.chrono.ChronoLocalDate
equality constraints(s): java.time.chrono.ChronoLocalDate,java.time.LocalDate)
method com.googlecode.cqengine.index.navigable.NavigableIndex.<A,O>onAttribute(com.googlecode.cqengine.index.support.Factory<java.util.concurrent.ConcurrentNavigableMap<A,com.googlecode.cqengine.resultset.stored.StoredResultSet<O>>>,com.googlecode.cqengine.index.support.Factory<com.googlecode.cqengine.resultset.stored.StoredResultSet<O>>,com.googlecode.cqengine.attribute.Attribute<O,A>) is not applicable
(cannot infer type-variable(s) A,O
(actual and formal argument lists differ in length))
Run Code Online (Sandbox Code Playgroud)
可能是缺少库设计:扩展的LocalDate实现,这意味着必须在泛型方法声明中使用通配符边界.我想,在这种情况下,创建实现的包装器是一种解决方法.ChronoLocalDateComparable<ChronoLocalDate>LocalDateComparable<>
也许,这个问题有其他一些解决方案吗?
我认为,创建新类(如包装器)会导致修复通用签名错误的开销很大.我想创建一个委托方法
@SuppressWarnings("unchecked")
static <A extends Comparable<A>,O>
NavigableIndex<A,O> onAttribute(Attribute<O,? extends A> attribute) {
return NavigableIndex.onAttribute((Attribute)attribute);
}
Run Code Online (Sandbox Code Playgroud)
实际上,问题在于声明A extends Comparable<A>应该是A extends Comparable<? super A>,但是在这里修复它无济于事,因为这种模式遍布整个API并允许这样的返回类型只会在下一个API使用时引发错误.但是,据我所知,Attribute只生产As但不消耗它们,我们可以在这里放松签名并接受Attribute<…,? extends A>遵循PECS模式的签名.
有了这个帮助器,你的代码应该顺利编译:
IndexedCollection<UtilizationEntry> entries = new ConcurrentIndexedCollection<>();
entries.addIndex(onAttribute(startDateAttr));
Run Code Online (Sandbox Code Playgroud)