DEV Community

Serguey Asael Shinder
Serguey Asael Shinder

Posted on

You Passed an int Array to Arrays.asList and contains Never Found a Thing

Three stores were closed
for a stocktake.

Orders for them
had to wait.

The rule was one line.

If the store is on the paused list,
hold the order.

It had worked for two years.

Then somebody tidied the config.

The paused stores
used to arrive as a list of Integer.

Now they arrived
as a plain int array,
smaller and faster,
and the check became this.

Arrays.asList(paused).contains(storeId)

It compiled.

The tests passed.

For three days
every order for those stores
went straight through
to a warehouse
that was counting boxes.

Nothing in that line is wrong
if you read it out loud.

Turn the array into a list.

Ask the list
if it has the number.

Here is what Java heard.

Arrays.asList takes
any number of things of type T,
and gives you a list of T.

T has to be an object.

int is not an object.

So Java did not unpack
the numbers one by one.

It took the only object it could see,
the array itself,
and made a list
with exactly one item in it.

A List of int arrays.

Size one.

Then contains
got the store number,
boxed it into an Integer,
and compared it
with the only thing in the list.

An array is never equal
to a number.

False.

Every time.

The compiler
had nothing to complain about,
because contains takes any Object.

And var
had hidden the type.

Write it out
and the mistake stops compiling.

List of Integer
equals Arrays.asList of an int array
is an error.

The same trap
sits in List.of
and in Stream.of.

Hand them an int array
and you get one element,
not three.

Even when it works,
with an Integer array,
asList is not the list you think.

It is a window
onto the array.

You cannot add to it
or remove from it.

Set an item
and the array changes underneath.

So for primitives
use the streams made for them.

Arrays.stream(paused),
anyMatch on the store number.

Or box them once,
on the way in,
into a Set of Integer,
and check that.

And test the rule
from the side that matters.

Not that a normal store
gets its order.

That a paused one
does not.

A check that never says yes
looks exactly like
a check with nothing to catch.

Until somebody counts the boxes.

– Serguey Asael Shinder

Top comments (0)