【问题标题】:How to make these two java methods generic如何使这两个java方法通用
【发布时间】:2018-01-02 03:33:02
【问题描述】:

我有这两种逻辑相同但参数不同的方法。如何将它们变成一种通用方法?

boolean exists(int[][] roads, int[] road){
    for(int[] r: roads){
       // code
    }
    return false;
}

boolean exists(ArrayList<int[]> roads, int[] road){
   for(int[] r: roads){
      // code
   }
    return false;
}

我想做这样的事情

<T> boolean exists(Collection<T[]> roads, T[] road){ 
    for(T[] r: roads){
         if(r[0] == road[0])
             return true; 
    }

    return false;
}

我收到如下类型错误:

required: Collection<T[]>,T[]
  found: int[][],int[]
  reason: cannot infer type-variable(s) T
    (argument mismatch; int[][] cannot be converted to Collection<T[]>)
  where T is a type-variable:
    T extends Object declared in method <T>exists(Collection<T[]>,T[])

我也尝试了其他一些签名,但它们也不起作用

  • &lt;T,F&gt; boolean exists(F&lt;T[]&gt; roads, T[] road)

  • &lt;T,F&gt; boolean exists(F&lt;? extends Object&gt; roads, T[] road)

【问题讨论】:

  • FWIW:X[] 永远不是Collection&lt;X&gt;
  • 让一种方法调用另一种方法。这样你只需要维护一个实现,但外部代码仍然可以调用对它们更方便的任何方法。

标签: java arrays generics arraylist


【解决方案1】:

Java 类型参数化无法为您提供将数组视为Collection反之亦然 的任何方法。您首先需要一个普通多态的基础,并且数组类型与非数组类型没有任何共同的超类型,适合您想要的多态实现。

我的建议是放弃对二维数组的直接支持作为参数。如果客户有一个他们想要传递给您的方法的二维数组,让他们使用Arrays.asList() 来获得一个List&lt;int[]&gt;,他们可以将其传递给该方法的基于集合的版本(但请阅读@987654324 的文档@ 了解有关此特定 List 实现的限制的信息)。

【讨论】:

  • +1,虽然不是指示客户端使用Arrays.asList(),但使用final boolean exists(int[][] roads, int[] road) { return this.exists(Arrays.asList(roads), road); } 重载方法可能更有意义。 (这是否有意义主要取决于预期该用例的普遍程度。)
【解决方案2】:

没有类型安全的方法可以做到这一点。您可以创建一个方法:

boolean exists(Object roads, int[] road)

并进行 instanceOf 检查和强制转换,但你失去的比得到的多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多