5 votes

Est-ce qu'un tableau 2D dynamique peut implémenter la méthode Java.Collection.size() ?

D'accord, donc je crée une array dynamique en 2D en Java qui implémente l'interface java.util.Collection. J'ai fait en sorte que mon array l'implémente parce que je voulais qu'il ait la même fonctionnalité qu'une Collection normale. Cependant, je ne peux pas implémenter la méthode size() parce que dans l'interface elle retourne un entier et une matrice en 2D pourrait potentiellement dépasser la capacité d'un type entier.

Voici un extrait de la classe que j'essaie de créer :

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

Maintenant, cela ne fonctionnera pas parce que "Le type de retour est incompatible avec Collection.size()", et si je change le type en int, columns * rows pourrait dépasser la capacité.

Je sais que je ne peux pas remplacer la méthode size de cette manière, mais y a-t-il un moyen de m'assurer que la méthode retourne la taille correcte tout en implémentant toujours l'interface Collection ?

Oui, je sais que c'est peu pratique et que cela ne posera probablement jamais de problème, mais j'étais curieux de savoir s'il y avait une bonne solution pour cela.

2voto

assylias Points 102015

Bien que votre implémentation de size soit discutable, le contrat de Collection#size est défini dans le javadoc:

Retourne le nombre d'éléments dans cette collection. Si cette collection contient plus de Integer.MAX_VALUE éléments, retourne Integer.MAX_VALUE.

Vous pourriez donc calculer la taille en tant que long, et retourner Integer.MAX_VALUE s'il est plus grand que Integer.MAX_VALUE.

Alternativement, vous pourriez imiter la façon dont c'est implémenté dans LinkedList#add par exemple, où size est simplement incrémenté et est autorisé à déborder.

2voto

Louis Wasserman Points 67557

En supposant que vous étiez prêt à avoir un tableau de 8 Go - la taille minimale d'un tableau bidimensionnel qui déborderait d'un int avec sa taille totale - et en supposant que vous étiez prêt à faire quelque chose d'intéressant avec cette collection, comme itérer dessus (coûtant plusieurs minutes au moins juste pour l'itération)...

Je crois que l'approche typique est soit de revenir à implémenter Iterable et non Collection, soit de simplement renvoyer Integer.MAX_VALUE, comme spécifié par la Javadoc:

Retourne le nombre d'éléments dans cette collection. Si cette collection contient plus d'éléments que Integer.MAX_VALUE, retourne Integer.MAX_VALUE.

0voto

Attila Points 18290

Si vous êtes vraiment préoccupé par des matrices suffisamment grandes qui pourraient déborder, vous pourriez vous assurer que cela ne se produise pas en vérifiant si la taille résultante (initialisation ou redimensionnement) resterait dans la plage des entiers, et en lançant une exception (exécution) si tel était le cas

-1voto

Wug Points 7672

Je ne pense pas, vous devrez probablement utiliser une solution de contournement de quelque sorte. Vous pourriez peut-être étendre votre taille pour retourner des nombres négatifs et les interpréter comme des entiers non signés de 32 bits, ce qui vous donnerait un maximum de 4 milliards et quelques.

Interrogez-vous cependant, avez-vous vraiment besoin de pouvoir prendre en charge autant d'objets? Gardez à l'esprit que 4 milliards et quelques entiers de 32 bits occuperont 16 Go de RAM. En utilisant Java 64 bits, un tableau long de 4 milliards d'Object défini sur null prendra 32 Go car les références sur Java 64 bits sont de 64 bits. Cela ne prend même pas en compte la mémoire utilisée pour instancier réellement autant de classes, ce qui sera très probablement bien plus élevé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X