Comment obtenir un sous-tableau de tableau en Java, sans copier les données?

J’ai une bibliothèque de classes, travaillant avec mes données, qui sont en cours de lecture dans un tampon. Est-il possible d’éviter de copier les baies encore et encore, en faisant passer des parties de données de plus en plus profondes dans les méthodes de traitement? Eh bien, cela semble étrange, mais dans mon cas particulier, il y a un graveur spécial, qui divise les données en blocs et les écrit individuellement dans différents emplacements, il exécute simplement System.arraycopy, obtient ce dont il a besoin et appelle un éditeur sous-jacent. sous tableau. Et cela arrive souvent. Quelle est la meilleure approche pour refactoriser un tel code?

De nombreuses classes en Java acceptent un sous-ensemble de tableaux comme paramètre. Par exemple, Writer.write (char cbuf [], int off, int len). Peut-être que cela suffit déjà pour votre compte d’utilisateur.

Arrays.asList(array).subList(x, y). 

Cette méthode ne vous donne pas un tableau, mais une List , qui est beaucoup plus flexible.

Il n’y a pas de véritable moyen d’ encapsuler des données sans les copier et de recevoir des données réelles en Java. Vous ne pouvez simplement pas créer un nouveau tableau sur la mémoire existante. Vous avez essentiellement 2 options:

  • Utilisez des méthodes pouvant accepter une plage de tableau. Cela était déjà recommandé.
  • Utilisez un wrapper qui fournit une sorte d’abstraction proche du tableau et convient à de nombreuses applications. Sera décrit ci-dessous.

Vous pouvez utiliser la hiérarchie des classes java.nio.Buffer , en particulier java.nio.ByteBuffer qui offre une abstraction de la mémoire tampon sur tout un tableau ou des sous-plages. C’est souvent ce dont les gens ont besoin. Cela offre également de nombreuses fonctionnalités intéressantes, telles que la méthode de copie inversée et la représentation flexible de la zone d’octets.

Voici un exemple d’encapsulation utilisant java.nio.ByteBuffer . Cela devrait être très proche de ce dont vous avez besoin. Au moins pour certaines opérations.

 byte [] a1 = {0, 0, 1, 0}; ByteBuffer buf = ByteBuffer.wrap(a1,1,2); 

Ensuite, vous pouvez faire avec n’importe ByteBuffer opération ByteBuffer .

Juste un avertissement, buf.array() renvoie le tableau original a1 (backend) avec tous les éléments.

Il n’y a aucun moyen de déclarer un sous-tableau en Java si vous utilisez des tableaux intégrés tels que byte []. La raison en est la suivante: la longueur du tableau est stockée avec les données et non avec la déclaration de la référence. Par conséquent, un sous-tableau qui ne copie pas les données n’a pas de place où il peut stocker la longueur! Donc, pour les types de base, vous pouvez utiliser les copies de tableau d’octets efficaces mentionnées et pour les types supérieurs (Liste), il existe des méthodes disponibles.

Vous pouvez suivre la même approche que la classe Ssortingng ; créer une classe pour les objects immuables qui sont construits à partir d’un tableau, un décalage de début et un décalage de fin qui offre un access au sous-tableau. L’utilisateur d’un tel object n’a pas à connaître la distinction entre le tableau entier ou un sous-tableau. Le constructeur n’a pas besoin de copier le tableau, stockez simplement la référence du tableau et ses limites.

Vous pouvez utiliser (ArrayList) .subList (value1, value2) Je crois, peut-être que cela pourrait aider dans votre cas? C’est bien sûr si vous voulez utiliser une ArrayList.

Consultez les méthodes Arrays.copyOfRange(***) .