簡體   English   中英

如何避免有關原始類型的代碼重復?

[英]How to avoid duplication of code regarding primitive types?

背景

位輸入流由字節數組支持。 有一些方法可以從該字節數組讀取到各種強制原始數組。

問題

有重復的代碼。 Java 缺乏原始類型的泛型,因此重復可能是不可避免的。

代碼

重復代碼在以下方法中很明顯:

@Override
public long readBytes(final byte[] out, final int offset, final int count, final int bits) {
    final int total = offset + count;

    assert out != null;
    assert total <= out.length;

    final long startPosition = position();

    for (int i = offset; i < total; i++) {
        out[i] = readByte(bits);
    }

    return position() - startPosition;
}

@Override
public long readShorts(final short[] out, final int offset, final int count, final int bits) {
    final int total = offset + count;

    assert out != null;
    assert total <= out.length;

    final long startPosition = position();

    for (int i = offset; i < total; i++) {
        out[i] = readShort(bits);
    }

    return position() - startPosition;
}

請注意final byte[] out如何與readByte(bits) ,就像final short[] outreadShort(bits) 這些關系是問題的症結所在。

如何消除重復,如果有的話,又不會導致顯着的性能損失(例如,通過自動裝箱)?

有關的

如果您正在閱讀代碼似乎表明的批量原語,則使用asDoubleBuffer()asShortBuffer()ByteBuffer方法將卸載一些最低級別的工作。

例子:

   public void readBytes( final byte[] out, final int offset, final int count, final ByteBuffer buffer ) {
      buffer.get( out, offset, count );  // udates ByteBuffer `position` automatically
   }

   public void readShorts( final short[] out, final int offset, final int count, final ByteBuffer buffer ) {
      ShortBuffer sb = buffer.asShortBuffer();
      sb.get( out, offset, count );  // note that `count` reads two bytes for each `short`
   }

(代碼編譯但未測試!)

一種會導致性能損失的可能性是使用java.lang.reflect.Array將數組視為一個對象,然后允許在所有讀取方法中重用相同的代碼。

@FunctionalInterface
public interface BitArrayReader {
    Object read(int bits);
}

private long readPrimitive(
        final Object out, final int offset, final int count, final int bits,
        final BitArrayReader reader) {
    final int total = offset + count;

    assert out != null;
    assert total <= Array.getLength(out);

    final long startPosition = position();

    for (int i = offset; i < total; i++) {
        Array.set(out, i, reader.read(bits));
    }

    return position() - startPosition;
}

@Override
public long readBooleans(boolean[] out, int offset, int count, int bits) {
    return readPrimitive(out, offset, count, bits, this::readBoolean);
}

以犧牲一些性能、輕微缺乏編譯時類型安全和使用反射為代價解決了重復問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM