El siguiente código compila y se ejecuta sin problemas:
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);
}
}
Estoy desconcertado con esta línea de código
res.add(Arrays.asList(nums[i],nums[j++],nums[k--]))
res
es de tipo HashSet<List<Integer>>
, y Arrays.asList
devuelve el valor de tipo ArrayList
(no java.util.ArrayList
, pero una clase definida internamente de acuerdo con java 8 código fuente , que también implementos java.util.List
)
¿Por qué NO añadiendo ArrayList
ejemplo, para una colección de List
excepción aumento?
Aunque el primero es subtipo de este último, por lo que conocer el funcionamiento adición no se debe permitir, porque HashSet<ArrayList>
no está subtipo de Set<List>
?
Citando el FAQ genéricos sobre la compatibilidad se está cuestionando:
Una
List<Object>
es compatible a unCollection<Object>
porque los dos tipos son ejemplificaciones de un supertipo genérico y su subtipo genérico y las instancias son para el mismo tipo de argumento objeto.
Los tipos que son incompatibles son aquellos relacionados (los) que tienen diferentes argumentos de tipo (caso si esos tipos de argumentos se tengan vínculos / compatibles) - la misma fuente:
Un
ArrayList<String>
objeto no se puede pasar como argumento a un método que pide unArrayList<Object>
porque los dos tipos son instancias del mismo tipo genérico, pero por diferentes argumentos de tipo, y por esta razón no son compatibles entre sí.
Esta:
Arrays.asList(nums[i],nums[j++],nums[k--]) //creating and adding List<Integer>
Está haciendo una instancia de la primera clase anterior.
Aunque el primero es subtipo de este último, por lo que yo sé la operación de suma no debe ser permitido porque
HashSet<ArrayList<Integer>>
no es del subtipoSet<List<Integer>>
Tiene un hecho mal aquí. El tipo de retorno de la estática Arrays.asList(nums[i],nums[j++],nums[k--])
es no ArrayList<Integer>
. Es List<Integer>
. Usted tiene una buena percepción de la clase en tiempo de ejecución que devuelve asList
, pero el compilador no se preocupa por que (excepto cuando se valida que el código en sí), se detiene en el tipo estático (el tipo de retorno declarado) del asList
, que en este caso es List<Integer>
.
Es cierto que HashSet<ArrayList<Integer>>
no es compatible con Set<List<Integer>>
, pero esto es irrelevante, ya que el compilador no está mirando a la clase en tiempo de ejecución real (incluso si esto es lo que se utiliza para crear una instancia del conjunto).
Por lo que yo puedo ver, todo lo que las necesidades del compilador para hacer cumplir aquí es que usted está llamando Set<List<Integer>>.add()
con un argumento que es una List<Integer>
, lo que usted está haciendo.