1

I expect that this code prints "0" since the starting size of the array is 0, but what it does is printing "1". Can someone explain me why, using Arrays.asList on an empty collection alter the size of the resulting collection? I know that "asList" gives back a fixed-size array but still I cannot imagine what's the reason behind that.

@Test
    public void checkEmptinessTest() {
        byte[] arrayOfTest = new byte[0];
        System.out.println(Arrays.asList(arrayOfTest).size());
    }

I tried to initialize the array with no items like this:

byte[] arrayOfTest = new byte[] = {};

but the result is the same. Thanks for the help.

Simone Lungarella
  • 301
  • 1
  • 4
  • 15
  • 5
    You have created a `List` containing one empty byte array, not a `List` that is empty. – Mark Rotteveel Jun 15 '21 at 16:25
  • `Arrays.asList(arrayOfTest)` returns a list or arrays so it contains a single element: an empty `byte[]`. – Thomas Jun 15 '21 at 16:26
  • 1
    If you put an empty box inside a bigger box, there is one box inside the bigger box. – Andy Turner Jun 15 '21 at 16:26
  • 1
    What might confuse you here is type inference. If you'd use `Arrays.asList(new Byte[0])` the generic type of `asList(T...)` could be `Byte` or `Byte[]` and the compiler will select `Byte`. However, if you call `Arrays.asList(new byte[0])` the only option would be `byte[]` because `byte` isn't a class but a primitive type. Thus `byte[]` will be selected as the type of `T`. – Thomas Jun 15 '21 at 16:32
  • Related: https://stackoverflow.com/a/1467940 (although it is about `int` same applies to `byte`) – Pshemo Jun 15 '21 at 16:32
  • @MarkRotteveel this is some interesting behavior. Will the results be different if `arrayOfTest` is a boxed type (i.e. `Byte[]`)? – Cardinal System Jun 15 '21 at 16:44
  • 1
    @CardinalSystem yes, using a Byte array instead of byte array gives what I expected, 0 as size and a list of Byte contained in the starting array. – Simone Lungarella Jun 16 '21 at 07:22

1 Answers1

2

Because you've made a list of byte arrays. Not a list of bytes.

In other words, your list contains 1 item: An empty byte array.

You can't easily turn a byte[] into a List<Byte>. There are slightly less trivial ways to do it (just do the obvious thing: Write a for loop), but note that a List<Byte> is about 10x more wasteful than a byte[]. Generally, you don't 'want' a List<Byte>, unless you are really very sure you do. Just about every byte-stream related API takes a byte[], In/OutputStream, or ByteBuffer, and rarely if ever a List<Byte>, for example.

EDIT: To be clear, if the component type is not a primitive, then lists are just as efficient as arrays are, in practice more efficient (because it is cleaner code, and that is the only feasible road to a non-trivially-sized project that performs well). It's just collections-of-primitives that are, and it's the worst, by far, when we're talking about byte[].

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72