Захватите сегмент массива в Java, не создавая новый массив в куче - PullRequest
180 голосов
/ 09 июля 2009

Я ищу метод в Java, который будет возвращать сегмент массива. Примером может быть получение байтового массива, содержащего 4-й и 5-й байты байтового массива. Я не хочу создавать новый массив байтов в памяти кучи только для этого. Прямо сейчас у меня есть следующий код:

doSomethingWithTwoBytes(byte[] twoByteArray);

void someMethod(byte[] bigArray)
{
      byte[] x = {bigArray[4], bigArray[5]};
      doSomethingWithTwoBytes(x);
}

Я хотел бы знать, был ли способ просто сделать doSomething(bigArray.getSubArray(4, 2)), где 4 - это смещение, а 2 - это, например, длина.

Ответы [ 15 ]

6 голосов
/ 09 июля 2009

List позволяют вам прозрачно использовать и работать с subList. Примитивные массивы требуют, чтобы вы отслеживали какой-то предел смещения. ByteBuffer s имеют похожие параметры, как я слышал.

Edit: Если вы отвечаете за полезный метод, вы можете просто определить его с помощью границ (как это делается во многих связанных с массивами методах в самой java:

doUseful(byte[] arr, int start, int len) {
    // implementation here
}
doUseful(byte[] arr) {
    doUseful(arr, 0, arr.length);
}

Однако не ясно, работаете ли вы с самими элементами массива, например Вы что-то вычисляете и записываете результат?

2 голосов
/ 07 февраля 2015

@ unique72 в качестве простой функции или строки, вам может потребоваться заменить Object на соответствующий тип класса, который вы хотите «нарезать». Два варианта даны для удовлетворения различных потребностей.

/// Extract out array from starting position onwards
public static Object[] sliceArray( Object[] inArr, int startPos ) {
    return Arrays.asList(inArr).subList(startPos, inArr.length).toArray();
}

/// Extract out array from starting position to ending position
public static Object[] sliceArray( Object[] inArr, int startPos, int endPos ) {
    return Arrays.asList(inArr).subList(startPos, endPos).toArray();
}
1 голос
/ 27 июня 2016

Мне нужно было пройти через конец массива и не хотел копировать массив. Мой подход состоял в том, чтобы сделать Iterable по массиву.

public static Iterable<String> sliceArray(final String[] array, 
                                          final int start) {
  return new Iterable<String>() {
    String[] values = array;
    int posn = start;

    @Override
    public Iterator<String> iterator() {
      return new Iterator<String>() {
        @Override
        public boolean hasNext() {
          return posn < values.length;
        }

        @Override
        public String next() {
          return values[posn++];
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException("No remove");
        }
      };
    }
  };
}
1 голос
/ 14 января 2011

Как насчет тонкой List обертки?

List<Byte> getSubArrayList(byte[] array, int offset, int size) {
   return new AbstractList<Byte>() {
      Byte get(int index) {
         if (index < 0 || index >= size) 
           throw new IndexOutOfBoundsException();
         return array[offset+index];
      }
      int size() {
         return size;
      }
   };
}

(непроверенная)

0 голосов
/ 06 июня 2014

Это немного легче, чем Arrays.copyOfRange - без диапазона или с отрицательным значением

public static final byte[] copy(byte[] data, int pos, int length )
{
    byte[] transplant = new byte[length];

    System.arraycopy(data, pos, transplant, 0, length);

    return transplant;
}
...