Подтвердить что ты не робот

Как получить вспомогательный массив массива в Java, без копирования данных?

У меня есть библиотека классов, работающая с моими данными, которая считывается в буфер. Возможно ли как-то избежать повторного копирования массивов, передавая части данных глубже и глубже в методы обработки? Ну, это звучит странно, но в моем конкретном случае есть специальный писатель, который делит данные на блоки и записывает их индивидуально в разные местоположения, поэтому он просто выполняет System.arraycopy, получает то, что ему нужно, и называет лежащего в основе автора, с этим новым sub. И это случается много раз. Каков наилучший подход для реорганизации такого кода?

4b9b3361

Ответ 1

Многие классы в Java принимают подмножество массивов в качестве параметра. Например. Writer.write(char cbuf [], int off, int len). Возможно, этого уже достаточно для вашего использования.

Ответ 2

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

Этот метод не дает вам массив, но List, который намного более гибкий.

Ответ 3

Нет реального способа переносить любые данные без копирования и получения реального arra y в Java. Вы просто не можете создать новый массив поверх существующей памяти. У вас есть в основном 2 варианта:

  • Используйте методы, которые могут принимать диапазон массива. Это было уже рекомендовано.
  • Используйте оболочку, которая дает некоторую абстракцию, близкую к массиву, и подходит для многих приложений. Ниже будет описано ниже.

Вы можете использовать иерархию классов java.nio.Buffer, особенно java.nio.ByteBuffer, которая предлагает абстракцию буфера для всего массива или поддиапазонов. Часто это то, что нужно людям. Это также предлагает много интересных возможностей, таких как отображение "нулевой копии" и гибкое представление байтовой области.

Вот пример обертывания с помощью java.nio.ByteBuffer. Это должно быть очень близко к тому, что вам нужно. По крайней мере, для некоторых операций.

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

Затем вы можете выполнить buf любую операцию ByteBuffer.

Просто предупреждение, buf.array() возвращает исходный массив a1 (бэкэнд) со всеми элементами.

Ответ 4

Невозможно объявить subarray в Java, если вы используете встроенные массивы типа byte []. Причина такова: длина массива хранится с данными, а не с объявлением ссылки на него. Следовательно, подрамник, который не копирует данные, не имеет места, где он может хранить длину! Таким образом, для базовых типов вы можете использовать упомянутые эффективные копии массива байтов, а для более высоких типов (Список) доступны доступные методы.

Ответ 5

Вы можете использовать тот же подход, что и класс String; создать класс для неизменяемых объектов, которые построены из массива, смещение начала и конечное смещение, которое предлагает доступ к подматрице. Пользователь такого объекта не должен знать различия между целым массивом или подматрицей. Конструктор не должен копировать массив, просто сохраните ссылку на массив и его границы.

Ответ 6

Вы можете использовать (ArrayList).subList(value1, value2) я belive, возможно, это может помочь в вашем случае? Это, конечно, если вы хотите использовать ArrayList.

Ответ 7

Возможно, вместо того, чтобы работать с массивами, вы должны работать с другим типом, который поддерживает ссылку на фрагмент исходного массива, вместо того, чтобы копировать данные, подобно ArraySegment в С#. Дополнительным преимуществом этого является то, что вы также можете сдвигать срез поверх исходного массива по требованию, не создавая новые экземпляры. Псевдокод:

public class ArraySegment<T> implements Iterable<T> 
{
      private int from, to;
      private T[] original;

      public ArraySegment<T>(T[] original, int from, int to)
      {
          //constructor stuff
      }

      public T get(int index)
      {
           return source[index + from];
      }

      public int size()
      {
          return to - from + 1;
      }

      @Override
      public Iterator<T> iterator()
      {
          //Iterator that iterates over the slice
      }

      //Can support setters on from/to variables
}

Ответ 8

Посмотрите на методы Arrays.copyOfRange(***).