Есть ли эквивалент в memcpy () в Java? - PullRequest
70 голосов
/ 25 июля 2010

У меня есть байт [], и я хотел бы скопировать его в другой байт [].Может быть, я показываю здесь свой простой фон 'C', но есть ли эквивалент в memcpy () для байтовых массивов в Java?

Ответы [ 8 ]

91 голосов
/ 25 июля 2010

Использование System.arraycopy ()

System.arraycopy(sourceArray, 
                 sourceStartIndex,
                 targetArray,
                 targetStartIndex,
                 length);

Пример

String[] source = { "alpha", "beta", "gamma" };
String[] target = new String[source.length];
System.arraycopy(source, 0, target, 0, source.length);


или используйте Arrays.copyOf ()
Пример,

target = Arrays.copyOf(source, length);

java.util.Arrays.copyOf(byte[] source, int length) был добавлен в JDK 1.6.

Метод copyOf() использует System.arrayCopy() для создания копии массива, но он более гибкий, чем clone(), поскольку вы можете создавать копии частей массива.

81 голосов
/ 25 июля 2010

Вы можете попробовать System.arraycopy или использовать функции массива в классе Arrays, например java.util.Arrays.copyOf. Оба должны дать вам родную производительность под капотом.

Arrays.copyOf, вероятно, удобен для удобства чтения, но был введен только в Java 1.6.

 byte[] src = {1, 2, 3, 4};
 byte[] dst = Arrays.copyOf(src, src.length);
 System.out.println(Arrays.toString(dst));
7 голосов
/ 25 июля 2010

Если вы просто хотите получить точную копию одномерного массива, используйте clone().

byte[] array = { 0x0A, 0x01 };
byte[] copy = array.clone();

Для других операций копирования массива используйте System.arrayCopy / Arrays.copyOf как Том предлагает .

В общем, следует избегать clone, но это исключение из правила.

5 голосов
/ 25 июля 2010

Вы можете использовать System.arrayCopy .Он копирует элементы из исходного массива в целевой массив.Реализация Sun использует оптимизированный вручную ассемблер, так что это быстро.

3 голосов
/ 30 октября 2013

В Java действительно есть что-то вроде memcpy ().Класс Unsafe имеет метод copyMemory (), который по сути идентичен memcpy ().Конечно, как и memcpy (), он не обеспечивает защиту от наложения памяти, уничтожения данных и т. Д. Не ясно, действительно ли это memcpy () или memmove ().Его можно использовать для копирования с реальных адресов на реальные адреса или из ссылок на ссылки.Обратите внимание, что если используются ссылки, вы должны указать смещение (или JVM умрет как можно скорее).

Unsafe.copyMemory () работает (до 2 ГБ в секунду на моем старом уставшем ПК).Используйте на свой риск.Обратите внимание, что класс Unsafe существует не для всех реализаций JVM.

2 голосов
/ 25 июля 2010

Вы можете использовать System.arraycopy

1 голос
/ 19 января 2019

Нет. Java не имеет эквивалента memcpy. Java имеет эквивалент memmove вместо.

Если аргументы src и dest ссылаются на один и тот же объект массива, то копирование выполняется так, как если бы компоненты в позициях от srcPos до srcPos + length-1 сначала были скопированы во временный массив с компонентами длины, а затем с содержимым временный массив был скопирован в позиции destPos через destPos + length-1 массива назначения.

Документы Oracle

Весьма вероятно, что System.arraycopy никогда не будет иметь такую ​​же производительность, как memcpy, если src и dest ссылаются на один и тот же массив. Обычно это будет достаточно быстро.

0 голосов
/ 05 января 2019

Использовать byteBufferViewVarHandle или byteArrayViewVarHandle.

Это позволит вам скопировать массив "longs" непосредственно в массив "doubles" и подобный с чем-то вроде:

public long[] toLongs(byte[] buf) {
    int end = buf.length >> 3;
    long[] newArray = new long[end];
    for (int ii = 0; ii < end; ++ii) {
        newArray[ii] = (long)AS_LONGS_VH.get(buf, ALIGN_OFFSET + ii << 3);
    }
}

private static final ALIGN_OFFSET = ByteBuffer.wrap(new byte[0]).alignmentOffset(8); 
private static final VarHandle AS_LONGS_VH = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.nativeOrder());

Это позволит вам взломать бит как:

float thefloat = 0.4;
int floatBits;
_Static_assert(sizeof theFloat == sizeof floatBits, "this bit twiddling hack requires floats to be equal in size to ints");
memcpy(&floatBits, &thefloat, sizeof floatBits);
...