Java añadir instancia subtipo a una colección de supertipo?

Zoz:

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--]))

reses de tipo HashSet<List<Integer>>, y Arrays.asListdevuelve 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 ArrayListejemplo, para una colección de Listexcepció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>?

ernest_k:

Citando el FAQ genéricos sobre la compatibilidad se está cuestionando:

Una List<Object>es compatible a un Collection<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 un ArrayList<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.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=313298&siteId=1
Recomendado
Clasificación