1

Consider I have an enumeration:

public enum MyEnum {
    SUCCESS;
}

I also have a string represented as a byte[]:

byte[] bytes = aString.getBytes(Charset.forName("UTF8"));

I need a mechanism that will combine the 2 byte[] into a single array, enum followed by the string, and retrieve the data out the other end. The only way I can think of doing this is by converting the enumeration into a known fixed size byte[]. Then when I extract the data from a given byte[], I know the first x represent the enum, and the remainder the string. Then all I need to do is convert the first part of the byte[] back into an enumeration, and the remainder into a string with:

new String(byte[],Charset)

Any helpful utilities to aid me in this?

Clarification: The mechanism needs to be very quick, and the byte[] of the string has already been supplied via another mechanism. I need to create a byte[] for the enumeration, then simply combine the two. At the other end I need to extract the byte[] for the enumeration and string into separate byte[]. I need to turn the first byte[] into the enumeration, but the second byte[] representing the string is passed to somewhere else. Thus I do not want to create a single encapsulating data class containing an enumeration and string, the overhead is too much.

Marcus MacWilliam
  • 602
  • 1
  • 6
  • 24
  • 2
    It's unclear precisely what you're asking but it sounds very much like a hack/kludge. This may be an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). If you can step back a bit and present what you're trying to accomplish I bet there's a much cleaner solution. – TypeIA Jan 31 '18 at 15:24
  • I am dealing with a legacy system which is passing messages around as byte[]. In this case the message consists of 2 elements, an enumeration and a string. I need to convert a pair of these into a byte[], and then back into the separate enumeration and string. – Marcus MacWilliam Jan 31 '18 at 15:26
  • [This answer](https://stackoverflow.com/a/13174951/905488) shows an example using SerializationUtils. Then there is also Java's standard serialization mechanism (through `ObjectOutputStream`). – Mick Mnemonic Jan 31 '18 at 15:27
  • Sorry, I should have mentioned in the question, the mechanism has to be very fast, as optimal as possible. I have generally found that such utilities although very helpful, cannot be employed in systems that need to handle many transactions a second. – Marcus MacWilliam Jan 31 '18 at 15:33

3 Answers3

3

Some further investigation suggests this as a possible answer:

byte[] data = ... from somewhere else
byte[] message = new byte[data.length + 1]
message[0] = Integer.valueOf(MyEnum.SUCCESS.ordinal()).byteValue();
System.arrayCopy(data, 0, message, 1, data.length);
Marcus MacWilliam
  • 602
  • 1
  • 6
  • 24
1

Here is my another try. It should improve performance since the enum bytes[] are cashed...

enum Enum {
    SUCCESS;

    private static final int CONSTANT_LENGTH = 64;
    private static final byte[][] CACHE = new byte[Enum.values().length][CONSTANT_LENGTH];

    static {
        for (int i = 0; i < CACHE.length; i++) {
            CACHE[i] = Enum.values()[i].toString().getBytes();
            CACHE[i] = Arrays.copyOf(CACHE[i], CONSTANT_LENGTH);
        }
    }

    static byte[] getEnumBytes(Enum e) {
        return CACHE[e.ordinal()];
    }

    static Enum getEnum(byte[] bytes) {
        for (int i = 0; ii < CACHE.length; i++) {
            if (Arrays.equals(CACHE[i], bytes)) {
                return Enum.values()[i];
            }
        }
    }

}

And the calling might be this way:

System.out.println(Arrays.toString(Enum.getEnumBytes(Enum.SUCCESS)));

Please, notice that Enum also can be cashed in the similar way.

Marcus MacWilliam
  • 602
  • 1
  • 6
  • 24
zlakad
  • 1,314
  • 1
  • 9
  • 16
0

You can write something like this in your enum class (since enums are actually classes):

enum Enum {
    SUCCESS;

    static byte[] getEnumBytes(Enum e){
        byte[] result = e.toString().getBytes();
        //logic to make byte[] length constant for each Enum
        return result;
    };


    static Enum getEnum(byte[] bytes){
        //logic to retrieve Enum from bytes[] converted to String
        return Enum.valueOf("...");
    };

}
zlakad
  • 1,314
  • 1
  • 9
  • 16
  • That will not give me a fixed length byte[], the size will differ depending on the number of characters in the name of the enumeration. – Marcus MacWilliam Jan 31 '18 at 15:39
  • If you're noticed I wrote in the commentated line that you'll have to write the logic to ensure that the `getBytes` returns the fixed byte[] length (maybe to add some zeros at the end)... – zlakad Jan 31 '18 at 15:41
  • This is also very inefficient as it is converting the name of the enumeration element into a byte[], I would have thought the ordinal integer value would be a much better, and quicker mechanism. – Marcus MacWilliam Jan 31 '18 at 15:44