chimeracoder
chimeracoder

Reputation: 21682

2D Array in Java, Indexed by Characters

Unless I'm mistaken, it is legal to have an array in Java indexed by character values, since these are equivalent to 8-bit numbers. However, the following code generates error messages for me:

int[][] myArray = new int[256][256];
myArray['%']['^'] = 25;

Is there a way to make this work?

edit: Wow, I really didn't do a good job of copying over the code.

Upvotes: 0

Views: 3166

Answers (4)

Sergei Tachenov
Sergei Tachenov

Reputation: 24879

Characters are equivalent to unsigned 16-bit integer, but that's really an awful design flaw in Java and shouldn't be abused. Conceptually, the char type stands for a character, not some integral value that happens to be mapped to a character (or even to a part of a character, in case of surrogate pairs).

The Map interface should be used to map something to something. Arrays should only be used when the index type is a full-fledged integer type, meaning to be used as such. And when these indexes don't fit into a fixed interval, so you don't know the array size in advance, it's better to use a Map for mapping integers either, rather than resizing the array each time.

Also consider memory usage. For 8-bit characters (ASCII) you can get away with 256x256x4 = 256K bytes of memory. But you kill the very possibility of internationalizing your application this way, which is a serious crime. To support the whole 16-bit range you'll need 64Kx64Kx4 = 16G bytes! And you still won't have the full support for characters outside that range, but then again you won't have it with a Map either, that's Java's flaw, not yours. It's not that it is needed by many anyway, though.

Upvotes: 1

Mohamed Mansour
Mohamed Mansour

Reputation: 40169

It is not illegal because in Java (and other languages), the char in this case will be casted to an int. Such as (int)'%'

Something like this would be safer if you don't know what type of char value it will be.

int[][] myArray = new int[Character.MAX_VALUE][Character.MAX_VALUE];
myArray['%']['^'] = 24;

It will work since Java will translate that to:

myArray[37][94] = 24;

Make sure you place max value of char (as already done) which is basically, '?' which translates to 65535. Or you will get an ArrayOutOfBoundsException.

If you know your range, you can still use 256. Just make sure you do proper bounds checking where the input is >=0 and < 256.

public int getItem(int x, int y) {
  if ((x < 0 && x > 255) || (y < 0 && y > 255)) {
    return -1; // Or you can throw an exception such as InvalidParameterException
  }
  return myArray[x, y];
}

Error bounds checking plays an important role for this.

I would rethink what your trying to do, something like this is unreadable, what are you trying to achieve? Perhaps you can use a different collections?

EDIT

Changed the types since you changed the code.

Upvotes: 2

trashgod
trashgod

Reputation: 205785

For reference, a Java char is a 16-bit unsigned quantity that is a valid array index, and "An Array of Characters is Not a String"

Upvotes: 0

Mihai Toader
Mihai Toader

Reputation: 12243

This works (i mean it compiles):

int[][] myArray = new int[256][256];
myArray['%']['^'] = 10;

Errors:

  1. you have different names for the arrays: first is myArray and the second is named table
  2. myArray is an array of arrays of int but you assigned a string to the cell.

Upvotes: 0

Related Questions