【问题标题】:Generics competence problem: Map<K, V> inside class / method without K and V in their signature泛型能力问题:类/方法内部的 Map<K, V> 签名中没有 K 和 V
【发布时间】:2021-10-24 02:55:01
【问题描述】:

请向我咨询我可能很愚蠢的问题。

我为我的问题准备了一点抽象的解释。 请不要尝试在您的计算机上重复它,这只是为了展示逻辑。

我的班级如下(同样,这只是为了说明):

public class Operation<D1, D2, R> extends AbstractOperation<D1, D2> implements InterfaceOperation<D1, D2, R> {

    @Override
    public Collection<R> doOperation(Collection<D1> collection_1, Collection<D2> collection_2) {    

        Map<String, String> map_1 = createMap_1(collection_1);
        Map<String, String> map_2 = createMap_2(collection_2);

        return (Collection<R>) ... ;
    }
}

我有一个 类 Operation,它实现了合同 InterfaceOperation。抽象类内部只是一些常用方法。因此,OperationInterfaceOperationdoOperation(Collection collection_1, Collection collection_2) 的签名 无法更改。

D1D2是Collection内部的一种元素,进入doOperation方法。

所以,CollectionData 元素组成,我将它们映射到 map_1 >map_2.

Data 可以有任何对象的组合,它是通用的并且效果很好,但是,Map map_1 (第二个)限制我只能在 Data 中使用

我需要让这些地图(map_1map_2)是通用的,例如 Map map_1(对于map_2),但没有将 放入方法或类签名中:

public class Operation<D1, D2, R> extends AbstractOperation<D1, D2> implements InterfaceOperation<D1, D2, R> {

    @Override
    public Collection<R> doOperation(Collection<D1> collection_1, Collection<D2> collection_2) {


        Map<K, V> map_1 = createMap_1(collection_1);
        Map<K, V> map_2 = createMap_2(collection_2);

        return (Collection<R>) ... ;
    }
}

这怎么可能?如果这是泛型中的一个具体主题,请告诉我,我会阅读它。 或者不改变类/接口/方法签名是不可能的?

谢谢!

更新 #1: createMap_1createMap_2 方法位于 abstract class AbstractOperation 内部,如下所示:

public abstract class AbstractOperation<D1, D2> {

    protected Map<Integer, String> createMap_1(Collection<D1> collection_1) {
        return collection_1.stream()
                .map(e -> (Data<Integer, String>) e)
                .collect(Collectors.toMap(Data::getKey, DataRow::getValue));
    }
    ...
}

【问题讨论】:

  • 那么,createMap_1createMap_2 方法的签名是什么?
  • 亲爱的 Ale,我已经用整个方法体更新了我的问题。谢谢。
  • 看起来这些应该在Operation 的子类中,将特定类型分配给D1D2R,例如class StringOperation extends Operation&lt;String, String, String&gt; { ... }.
  • 亲爱的 Louis,D1、D2 和 R 是 Collection 类型。我从这些集合中提取对象 Data 并将它们放入 Map,但 map 不是通用的,但必须是通用的。或者我必须取出地图并仅使用集合进行操作...我应该有可能将任何类型的对象放入 Data 中,但由于 Map 它们只能是类型,我在 Maps 中编写。
  • 泛型的重点是你永远不需要转换任何东西。使实际类型显式化的具体子类是预期的解决方案。如果KV 只能是IntegerString,因为那是createMap_1 的实际实现,那么泛型应该反映这一点。

标签: java generics collections


【解决方案1】:

如果您的doOperation 方法不关心这些映射的键和值的类型,您可以使用wildcards

Map<?, ?> map_1 = createMap_1(collection_1);
Map<?, ?> map_2 = createMap_2(collection_2);

请注意,这限制了您可以在地图上安全执行的操作类型。例如,如果没有不安全的强制转换,您将无法将值放入映射中或从映射中获取值,因为此方法不知道要使用的键的类型。

【讨论】:

  • 亲爱的蒂姆,您的解决方案有效,谢谢!奇怪的是,我没有想出这个……Ale Zalazar 和 Louis Wasserman(以及其他尝试过的人)也谢谢你!
猜你喜欢
  • 2011-12-02
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
  • 2018-11-23
  • 2019-07-30
  • 2019-01-23
  • 1970-01-01
相关资源
最近更新 更多