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 lues dans buffer. Est - il possible d'éviter de copier des tableaux encore et encore, en passant des parties de données de plus en plus profondément dans les méthodes de traitement? Eh bien, cela semble étrange, mais dans mon cas particulier, il y a un écrivain spécial, qui divise les données en blocs et les écrit individuellement dans différents endroits, donc il exécute simplement le système.arraycopy, obtient ce dont il a besoin et appelle writer sous-jacent, avec ce nouveau sous-programme tableau. Et cela arrive plusieurs fois. Quelle est la meilleure approche pour refactoriser un tel code?

46
demandé sur Roman Nikitchenko 2010-08-03 14:17:13

7 réponses

De nombreuses classes en Java acceptent un sous-ensemble d'un tableau comme paramètre. Par exemple écrivain.écrire (char cbuf [], int off, int len). Peut-être que cela suffit déjà pour votre utilisationcas.

21
répondu Markus Kull 2010-08-03 10:42:45
Arrays.asList(array).subList(x, y).

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

59
répondu Ricky Clarkson 2014-06-06 20:54:26

Il N'y a pas de véritable moyen deenvelopper des données sans copier et recevoir de vrais arra y en Java. Vous ne pouvez tout simplement pas créer de nouveau tableau sur la mémoire existante. Vous avez essentiellement 2 options:

  • utilisez des méthodes qui peuvent accepter la plage de tableau. Cela a déjà été recommandé.
  • utilisez un wrapper qui donne une sorte d'abstraction proche du tableau et qui convient à de nombreuses applications. Qui va être décrit ci-dessous.

Vous pouvez utiliser la hiérarchie des classes java.nio.Buffer, en particulier {[2] } qui offre une abstraction de tampon sur un tableau entier ou des sous-plages. C'est souvent ce que les gens ont besoin. Cela offre également de nombreuses capacités intéressantes comme flip "zéro copie" et la représentation de la zone d'octet flexible.

Voici un exemple d'emballage en 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 sur buf n'importe quelle opération ByteBuffer.

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

9
répondu Roman Nikitchenko 2017-12-25 12:35:06

Il N'y a aucun moyen de déclarer un sous-tableau en Java si vous utilisez des tableaux intégrés comme byte []. La raison en est: la longueur du tableau est stockée avec les données, pas 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 plus élevés (liste), il existe des méthodes disponibles.

3
répondu Joachim 2014-10-31 15:21:53

Vous pouvez adopter la même approche que la classe String; créez une classe pour les objets immuables qui sont construits à partir d'un tableau, d'un décalage de début et d'un décalage de fin qui offre un accès au sous-tableau. L'utilisateur d'un tel objet 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, il suffit de stocker la référence du tableau et ses limites.

2
répondu rsp 2010-08-03 10:35:12

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 un ArrayList.

1
répondu Kotten 2012-04-03 09:06:50

Jetez un oeil sur les méthodes Arrays.copyOfRange(***).

-1
répondu Manuel Selva 2010-08-03 10:21:35