2012-06-18 13 views
5

Bien, entonces estoy creando una matriz 2D dinámica en Java que implementa la interfaz java.util.Collection. Hice que mi array lo implementara porque quería que tuviera la misma funcionalidad que un Collection normal. Sin embargo, no puedo implementar el método size() porque en la interfaz devuelve un número entero y una matriz 2D podría desbordar un tipo entero.¿Puede una matriz 2D dinámica implementar el método Java.Collection.size()?

He aquí un fragmento de mi clase que estoy tratando de hacer:

public abstract class AbstractMatrix<E> implements Collection<E>{ 
    @Override 
    public long size() { 
     return columns * rows; 
    } 
} 

Ahora, esto no funcionará porque "El tipo de retorno es incompatible con Collection<E>.size()", y si puedo cambiar el tipo de int , columnas * filas podrían desbordarse.

Sé que no puedo anular el método de tamaño de esta manera, pero ¿hay alguna manera de asegurarme de que el método devuelve el tamaño correcto mientras sigo implementando la interfaz Collection?

Sí, sé que esto no es práctico y es probable que nunca sea un problema, pero me interesaba saber si había una buena solución para ello.

+0

Un desbordamiento como en una matriz de más de 45k filas x 45k columnas (suponiendo que sea cuadrado)? – assylias

+0

¿Planea tener más de 2,147,483,647 elementos? –

+0

¿Qué podrías hacer * con un 'tamaño' que sea' columnas * filas'? ¿Qué te dejaría hacer con la matriz? – sudocode

Respuesta

2

Aunque su implementación de size es cuestionable, el contrato para Collection#size se define en the javadoc:

Devuelve el número de elementos de esta colección. Si esta colección contiene más de elementos Integer.MAX_VALUE, devuelve Integer.MAX_VALUE.

por lo que podría calcular el tamaño que un long, y volver Integer.MAX_VALUE si es más grande que Integer.MAX_VALUE.

Como alternativa, podría imitar la forma en que se implementa en LinkedList#add, por ejemplo, donde size simplemente se incrementa y se permite que se desborde.

-1

Creo que no, tendrá que utilizar una solución de algún tipo. Tal vez podría ampliar su tamaño para devolver números negativos e interpretarlos como enteros de 32 bits sin signo, lo que le daría un máximo de 4 mil millones y cambiaría.

Pregúntate a ti mismo, ¿realmente necesitas ser capaz de soportar tantos objetos? Tenga en cuenta que 4 billones y cambiar enteros de 32 bits ocupará 16GB de RAM. Usando 64 bits Java, una matriz larga de 4 mil millones de Object configurada como nula ocupará 32 GB porque las referencias en 64 bits Java son 64 bits. Eso ni siquiera tiene en cuenta la memoria utilizada para crear una instancia de muchas clases, que con toda probabilidad será mucho más alta.

+0

Sí, me doy cuenta de que no es práctico tener una matriz 2D que se desborde así, pero solo preguntaba si había una solución. – Wires77

+0

¿Ha considerado mirar el código de ArrayList? ¿Por qué el tipo de devolución debe ser largo de todos modos? – branchgabriel

+0

mugafuga: ArrayLists son Colecciones, y solo tienen 'int size()', no 'long size()'. – Wug

0

Si está realmente preocupado con matrices lo suficientemente grandes que podrían desbordarse, podría asegurarse de que eso no ocurra comprobando si el tamaño resultante (inicialización o cambio de tamaño) aún estaría dentro del rango de entero, y arroje un (tiempo de ejecución) excepción si eso sería el caso

2

Suponiendo que estuviera dispuesto a tener una matriz de 8 GB: el tamaño mínimo de una matriz bidimensional que desbordará un int con su tamaño total, y suponiendo que estuviera dispuesto a hacer algo interesante con esa colección, como iterar sobre eso (costando varios minutos al menos solo para la iteración) ...

creo que el enfoque típico es o bien a dar marcha atrás a la implementación Iterable y no Collection, o simplemente para volver Integer.MAX_VALUE, según lo especificado por el Javadoc:

Devuelve el número de elementos de esta colección. Si esta colección contiene más de elementos Integer.MAX_VALUE, devuelve Integer.MAX_VALUE.

+1

Curiosamente, LinkedList # add permite desbordamiento de tamaño sin comprobación. – assylias

+0

No es tan sorprendente; su memoria generalmente se agotará mucho antes de que comience a atacar este tipo de problemas. (Además, es difícil imaginar un uso para 'LinkedList's que se pueda escalar a tantos elementos, en primer lugar). –

Cuestiones relacionadas