Java 静态Lists.transform标记为错误,但Collections.transform使用相同的变量有效

Java 静态Lists.transform标记为错误,但Collections.transform使用相同的变量有效,java,arraylist,guava,jooq,Java,Arraylist,Guava,Jooq,我正在尝试使用Guava static Collections2.transform和List.transform方法基于jooq记录类创建ArrayList。下面是生成result3记录的查询 final Table<Record3<Key<Store>, Key<Campaign>, String>> c1 = sql.dsl() .select(CAMPAIGN.STORE_KEY, CAMPAIGN.CAMP

我正在尝试使用Guava static Collections2.transform和List.transform方法基于jooq记录类创建ArrayList。下面是生成result3记录的查询

    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 Table c1=sql.dsl()
.选择(CAMPAIGN.STORE_键、CAMPAIGN.CAMPAIGN_键、标记)
.来自(活动)
.where(活动.活动密钥等于(活动密钥))
.asTable(“c1”);
最终表c2=sql.dsl()
.选择(CAMPAIGN.STORE_键、CAMPAIGN.CAMPAIGN_键、标记)
.来自(活动)
.asTable(“c2”);
最终结果result3=sql.dsl()
.选择(c1活动、计数(c2标记))
.从(c1,c2)
.where(c1.字段(“标记”,String.class).equal(c2.字段(“标记”,String.class)))
和(c1.字段(“存储密钥”,密钥.类)。相等(c2.字段(“存储密钥”,密钥.类)))
和(c1.字段(“活动密钥”,密钥.类)。notEqual(c2.字段(“活动密钥”,密钥.类)))
.groupBy(c2.字段(“活动密钥”,密钥类))
.orderBy(内联(2).desc())
.fetch();
以前,我有以下代码,在我意识到以后需要向集合添加值之前,这些代码运行良好,而创建的集合对象不支持这些值

    final Collection<Key<Campaign>> keys = Collections2.transform(result3, Record2::value1);
final Collection key=Collections2.transform(result3,Record2::value1);
由于这个问题,我试图切换到创建ArrayList,但当我添加以下内容时,我得到一个错误,即“无法从静态上下文引用非静态方法”

final ArrayList keys2=Lists.transform(result3,Record2::value1);

令人困惑的是,这两种变换方法都是静态的,并且它们在完全相同的对象上运行,那么为什么第一种方法有效而另一种方法无效呢?另外,如果第二种方法不起作用,我如何才能以这种方式生成ArrayList?

我发现在编译过程中看到了第二个错误,这让我找到了答案。我没有从Lists.transform创建ArrayList,而是将其更改为List,并且它可以正确编译

我发现在编译过程中看到的第二个错误指向了答案。我没有从Lists.transform中创建ArrayList,而是将它改为List,它可以正确编译

在实际处理这个问题之前,您需要了解Java和Guava的一些基本知识:

  • 在Java中,
    List
    不是
    ArrayList
    (但事实恰恰相反)ArrayList是接口
    List
    实现(许多可能的实现之一)
  • 您不能将
    List
    指定给
    ArrayList
    (至少在不强制转换的情况下,但这不是解决方案,也不是这里的选项)
  • 尽管您创建了
    ArrayList
    ,但在代码中使用具体实现并不是最佳做法,而是坚持使用接口(此处:
    List
  • 番石榴的
    Collections2.transform
    列表。transform
    返回用于创建视图的集合的惰性视图(,强调我的):

    返回的列表是fromList的转换视图;对fromList的更改将反映在返回的列表中,反之亦然。 (……)

    该函数是惰性应用的,在需要时调用。这对于返回的列表成为视图是必要的,但这意味着该函数将多次应用于诸如list.contains(java.lang.Object)和list.hashCode()之类的批量操作。要使其性能良好,功能应该是快速的。当返回的列表不需要是视图时,为了避免延迟计算,请将返回的列表复制到您选择的新列表中

  • 综上所述,在您的情况下,
    在复制到某个集合/列表或被消费之前不会计算任何内容,因此有效的方法是:

    final Collection<Key<Campaign>> keys = Collections2.transform(result3, Record2::value1);
    // later:
    final List<Key<Campaign>> keys2 = new ArrayList<>(keys); // here the function is applied
    

    在实际处理这个问题之前,您需要了解一些关于Java和番石榴的基本知识:

  • 在Java中,
    List
    不是
    ArrayList
    (但事实恰恰相反)ArrayList是接口
    List
    实现(许多可能的实现之一)
  • 您不能将
    List
    指定给
    ArrayList
    (至少在不强制转换的情况下,但这不是解决方案,也不是这里的选项)
  • 尽管您创建了
    ArrayList
    ,但在代码中使用具体实现并不是最佳做法,而是坚持使用接口(此处:
    List
  • 番石榴的
    Collections2.transform
    列表。transform
    返回用于创建视图的集合的惰性视图(,强调我的):

    返回的列表是fromList的转换视图;对fromList的更改将反映在返回的列表中,反之亦然。 (……)

    该函数是惰性应用的,在需要时调用。这对于返回的列表成为视图是必要的,但这意味着该函数将多次应用于诸如list.contains(java.lang.Object)和list.hashCode()之类的批量操作。要使其性能良好,功能应该是快速的。当返回的列表不需要是视图时,为了避免延迟计算,请将返回的列表复制到您选择的新列表中

  • 综上所述,在您的情况下,
    在复制到某个集合/列表或被消费之前不会计算任何内容,因此有效的方法是:

    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));
    
    List<Key<Campaign>> keys = result3.stream()
        .map(Record2::value1)
        .collect(Collectors.toList());