gpt4 book ai didi

Java 将子类型实例添加到父类(super class)型的集合中?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:05:16 26 4
gpt4 key购买 nike

以下代码编译运行没有问题:

class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Set<List<Integer>> res = new HashSet<>();
if(nums.length==0) return new ArrayList<>(res);
Arrays.sort(nums);
for(int i=0; i<nums.length-2;i++){
int j =i+1;
int k = nums.length-1;
while(j<k){
int sum = nums[i]+nums[j]+nums[k];
if(sum==0)res.add(Arrays.asList(nums[i],nums[j++],nums[k--]));
else if ( sum >0) k--;
else if (sum<0) j++;
}

}
return new ArrayList<>(res);
}
}

我对这行代码感到困惑

res.add(Arrays.asList(nums[i],nums[j++],nums[k--]))

res类型为 HashSet<List<Integer>> , 和 Arrays.asList返回 ArrayList 类型的值(不是 java.util.ArrayList ,而是根据 java 8 source code 的内部定义类,它也实现了 java.util.List )

为什么添加ArrayList实例到 List 的集合引发异常?

虽然前者是后者的子类型,但据我所知,添加操作是不允许的,因为HashSet<ArrayList>不是 Set<List> 的子类型?

最佳答案

引用generics FAQ关于您质疑的兼容性:

A List<Object> is compatible to a Collection<Object> because the two types are instantiations of a generic supertype and its generic subtype and the instantiations are for the same type argument Object.

不兼容的类型是那些(相关的)具有不同类型参数的类型(如果这些参数类型在其他方面是相关/兼容的事件) - 相同的来源:

A ArrayList<String> object cannot be passed as argument to a method that asks for a ArrayList<Object> because the two types are instantiations of the same generic type, but for different type arguments, and for this reason they are not compatible with each other.

这个:

  • Arrays.asList(nums[i],nums[j++],nums[k--]) //creating and adding List<Integer>

正在做上面第一种的实例化。


Although the former is subtype of latter, as far as I know the adding operation should not be allowed because HashSet<ArrayList<Integer>> is not subtype of Set<List<Integer>>

你在这里有一个错误的事实。 Arrays.asList(nums[i],nums[j++],nums[k--]) 的静态返回类型不是 ArrayList<Integer> .这是List<Integer> .您对 asList 返回的运行时类有很好的了解。 ,但编译器并不关心这一点(除了验证该代码本身),它停止在 asList 的静态类型(声明的返回类型)处。 ,在本例中为 List<Integer> .

HashSet<ArrayList<Integer>> 是真的与 Set<List<Integer>> 不兼容,但这无关紧要,因为编译器没有查看实际的运行时类(即使这是您用来实例化集合的类)。
据我所知,编译器在这里需要强制执行的是你调用Set<List<Integer>>.add()。参数是 List<Integer> ,你正在做的。

关于Java 将子类型实例添加到父类(super class)型的集合中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58281765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com