【问题标题】:creating a generic remapping function创建一个通用的重映射函数
【发布时间】:2020-03-25 14:34:53
【问题描述】:

我有一个充满不同列表的类,我想要一种简单的方法来重新映射它们的值。 所以我尝试创建一个像这样的通用重映射方法

private List<Row> list = new ArrayList<>();

@Builder(toBuilder = true)
@Data
private class Row {
    private String data;
}
public <T> void reMap(Class<T> builderClass, Function<T, T> rowMapper) {
    if(builderClass.equals(Row.class)) {
        list = list.stream().map(Row::toBuilder).map(rowMapper).map(Row::build).collect(Collectors.toList());
    }
}

但它抱怨rowMapper

reason: no instance(s) of type variable(s) exist so that RowBuilder conforms to T

很难理解为什么会这样,以及是否有合适的解决方法?

【问题讨论】:

  • 如果你只为一个特定的类做任何事情,为什么还需要一个泛型函数?
  • builderClass参数的作用是什么?
  • 基本上是因为我不想在每个列表中都使用reMap 函数来弄乱我的班级。我的示例确实缩短了,实际上我有近 20 个列表,如果避免使用 20 个几乎相同的 reMap 函数会非常好
  • @Sweeper 我的想法是能够在运行时将 T 绑定到实际类型。如果我没记错的话(我可能没有记错),如果 Java 编译器没有绑定到诸如类之类的东西,它会清除所有泛型类型
  • 注意:Function&lt;T, T&gt; 可以重写为UnaryOperator&lt;T&gt;

标签: java generics java-stream


【解决方案1】:

很难理解为什么会这样,以及是否有合适的解决方法?

简单的答案是:因为你(能够)比编译器知道的更多。

您正在检查 builderClass 是否为 Row。在这种情况下,编译器不会“记住”:也就是说,您必须继续告诉编译器它是,例如通过铸造。

但是,编译器对RowRowBuilder 类之间的关系一无所知。就类型系统而言,没有关系:它们只是两个类。

那么,有没有一个体面的方法来解决这个问题?不,不是真的。如果可能,尽量不要使用泛型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-19
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 2016-12-21
    • 2021-12-24
    • 2013-09-26
    相关资源
    最近更新 更多