我正在尝试使用Guava静态Collections2.transform和Lists.transform方法基于jooq Record类创建一个ArrayList。下面是生成result3 Record的查询。
final Table<Record3<Key<Store>, Key<Campaign>, String>> c1 = sql.dsl()
.select(CAMPAIGN.STORE_KEY, CAMPAIGN.CAMPAIGN_KEY, tag)
.from(CAMPAIGN)
.where(CAMPAIGN.CAMPAIGN_KEY.equal(campaignKey))
.asTable("c1");
final Table<Record3<Key<Store>, Key<Campaign>, String>> c2 = sql.dsl()
.select(CAMPAIGN.STORE_KEY, CAMPAIGN.CAMPAIGN_KEY, tag)
.from(CAMPAIGN)
.asTable("c2");
final Result<Record2<Key, Integer>> result3 = sql.dsl()
.select(c1Campaign, count(c2Tag))
.from(c1, c2)
.where(c1.field("tag", String.class).equal(c2.field("tag", String.class)))
.and(c1.field("store_key", Key.class).equal(c2.field("store_key", Key.class)))
.and(c1.field("campaign_key", Key.class).notEqual(c2.field("campaign_key", Key.class)))
.groupBy(c2.field("campaign_key", Key.class))
.orderBy(inline(2).desc())
.fetch();
以前我有以下代码正常工作,直到我意识到我需要稍后为集合添加值,而创建的集合对象不支持这些值。
final Collection<Key<Campaign>> keys = Collections2.transform(result3, Record2::value1);
由于这个问题,我试图切换到创建一个ArrayList,但是当我添加以下内容时,我得到一个错误说&#34;非静态方法无法从静态上下文中引用&#34;
final ArrayList<Key<Campaign>> keys2 = Lists.transform(result3, Record2::value1);
令人困惑的是,转换方法都是静态的,它们是在完全相同的对象上运行的,为什么第一个工作而不是另一个?如果第二种方法不起作用,我怎样才能以这种方式完成ArrayList的生成?
答案 0 :(得分:0)
我发现编译时遇到的第二个错误指向了答案。我没有从Lists.transform创建一个ArrayList,而是将其更改为List并正确编译
答案 1 :(得分:0)
在实际处理问题之前,您需要了解有关Java和Guava的基本知识:
public void RefreshAll()
{
// Get all objects in statemanager with entityKey
// (context.Refresh will throw an exception otherwise)
var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(
EntityState.Deleted
| EntityState.Modified
| EntityState.Unchanged)
where entry.EntityKey != null
select entry.Entity);
context.Refresh(RefreshMode.StoreWins, refreshableObjects);
}
不是List<Key>
(但情况恰恰相反) - ArrayList<Key>
是接口的实现(很多可能之一) ArrayList
。List
分配给List
(至少没有强制转换,但这不是解决方案,也不是此处的选项)。ArrayList
,在代码中使用具体实现也不是最佳做法,而是坚持使用接口(此处:ArrayList
)。 Guava的List
和Collections2.transform
返回用于创建视图的集合的 lazy views (from javadoc,强调我的):
返回的列表是fromList 的转换视图;对fromList的更改将反映在返回的列表中,反之亦然。 (...)
懒惰地应用该函数,在需要时调用。这对于返回的列表是视图是必要的,但这意味着该函数将多次应用于List.contains(java.lang.Object)和List.hashCode()等批量操作。为了表现良好,功能应该很快。要在返回的列表不需要是视图时避免延迟评估,请将返回的列表复制到您选择的新列表中。
尽管如此,Lists.transform
在你的情况下不会评估任何东西,直到复制到某个集合/列表或消费,所以有效的方法是:
keys
或
final Collection<Key<Campaign>> keys = Collections2.transform(result3, Record2::value1);
// later:
final List<Key<Campaign>> keys2 = new ArrayList<>(keys); // here the function is applied
困扰我的是你使用方法引用(final List<Key<Campaign>> keys2 = new ArrayList<>(Lists.transform(result3, Record2::value1));
)表明你已经在使用Java 8.如果你这样做,请使用Streams API:
Record2::value1