当前位置: 首页 > 知识库问答 >
问题:

如何限制泛型类型(问题比看起来更难)

康元凯
2023-03-14

好吧,问题并不像标题中看起来那么简单。

让我们从头开始。假设有两个包含DataRow对象的集合:

public class DataRow<K, V> {
    K key;
    V value;

    public DataRow(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public V getValue() {
        return value;
    }
}

伪代码示例如下:

c1 = [DataRow(0, "Italy"), DataRow(1, "Germany"), DataRow(2, "France")]
c2 = [DataRow(0, "Rome"), DataRow(1, "Berlin"), DataRow(3, "Budapest")]

在JoinedDataRow的一个集合中,需要有三种不同的方式连接这些集合(内部连接、左连接、右连接):

public class JoinedDataRow<K, V1, V2> {
    K key;
    V1 value1;
    V2 value2;

    public JoinedDataRow(K key, V1 value1, V2 value2) {
        this.key = key;
        this.value1 = value1;
        this.value2 = value2;
    }

    public K getKey() {
        return key;
    }

    public V1 getValue1() {
        return value1;
    }

    public V2 getValue2() {
        return value2;
    }
}

操作类似于SQL语言中的操作。内连接的结果示例:[JoinedDataRow(0,"意大利","罗马"), JoinedDataRow(1,"德国","柏林")]

这些操作的实现有一个称为JoinOperation的接口:

public interface JoinOperation<D1, D2, R> {
    Collection<R> join(Collection<D1> leftCollection, Collection<D2> rightCollection);
}

其中 D1 和 D2 是 DataRow 的,R 是 JoinedDataRow(结果)

接口有3种实现:InnerJoin、LeftJoin、RightJoin

无需为所有三个实现提供代码。这只是InnerJoin的框架:

public class InnerJoinOperation<D1, D2, R> implements JoinOperation<D1, D2, R> {
    @Override
    public Collection<R> join(Collection<D1> leftCollection, Collection<D2> rightCollection) {
        return null;
    }
}

问题:例如,现在传递到整数的连接方法集合是可能的,也是完全合法的。

join()方法应如下所示以避免:

@Override
    public Collection<JoinedDataRow<K, V1, V2>> join(Collection<DataRow<K, V1>> leftCollection, Collection<DataRow<K, V2>> rightCollection) {
        return null;
    }

但是禁止修改接口 JoinOperation,因此上述方法无效。

问题是:如何限制join方法中传递的参数的类型,这样就不可能传递除DataRow之外的任何内容。

我试过了:

public class InnerJoinOperation<D1 extends DataRow, D2 extends DataRow, R extends JoinedDataRow> implements JoinOperation<D1, D2, R> {
    @Override
    public Collection<R> join(Collection<D1> leftCollection, Collection<D2> rightCollection) {
        return null;
    }
}

但这里我使用的是原始数据行,当我想这样做时:

Collection<DataRow<Integer, String>> lCollection = new ArrayList<>(List.of(
                new DataRow<>(0, "Italy"),
                new DataRow<>(1, "Germany"),
                new DataRow<>(2, "France")
        ));

        Collection<DataRow<Integer, String>> rCollection = new LinkedList<>(List.of(
                new DataRow<>(0, "Rome"),
                new DataRow<>(1, "Berlin"),
                new DataRow<>(3, "Budapest")
        ));

        var joiner = new InnerJoinOperation<>();

        var joined = joiner.join(lCollection, rCollection);

expression < code > joiner . join(l collection,rCollection)显示编译时错误:在此输入图像描述

共有1个答案

郝原
2023-03-14

听起来你想要的只是

public class InnerJoinOperation<K, V1, V2>
    implements JoinOperation<DataRow<K, V1>, DataRow<K, V2>, JoinedDataRow<K, V1, V2>> {
  @Override
  public Collection<JoinedDataRow<K, V1, V2>> join(Collection<DataRow<K, V1>> leftCollection, Collection<DataRow<K, V2>> rightCollection) {
    return null;
  }
}
 类似资料:
  • 问题内容: 说,我有如下通用类型 我想让它只接受特定的类型(字符串/整数/双精度)。我知道有界通配符,但在这里对我没有帮助。在setVar()中,如果类型不是Integer / String等,我可以检查并引发异常。这是最好的方法吗? 在对此类型进行操作时,我遇到同样的问题。根据类型,我想执行不同的操作。继承和有界通配符似乎通常是解决此类问题的方法,但它们是原始包装器。 问题答案: 使用继承: P

  • 问题内容: 我上课了。我怎么能说我想成为某个班级的实施者?编写根本无法编译。 问题答案: 使用代替。

  • 问题内容: 在Java中,我编写了一个Binary Search Tree类,该类使用递归添加节点。现在,我想使用泛型对其进行概括,以便我可以了解更多有关它们的信息。 我添加节点的功能在以下类中 主类具有以下代码来开始工作。我正在使用字符串,但是数据类型可能是一些复杂的类型。 我开始使用Comparable接口,但是如何编写CompareTo()函数?我不知道T是什么类型的?我得到的错误是“运算符

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类

  • 问题内容: 现在,我希望能够查看so中是否包含对象: 如果您发现此功能属于扩展名。问题是如果将其添加到此: 我收到以下错误: 找不到’==’的重载,该重载接受提供的参数 我了解我可能需要告诉什么样的对象应该在里面,例如:。但这还不起作用: 括号中的语句块是未使用的闭包 非标称类型’T []’无法 扩展 问题答案: 使用Swift时,我们需要考虑是否有一个 函数 可以解决问题-在类的方法之外。 就像