Reputation: 21682
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
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
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
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
Reputation: 12243
This works (i mean it compiles):
int[][] myArray = new int[256][256];
myArray['%']['^'] = 10;
Errors:
myArray
and the second is named table
int
but you assigned a string to the cell. Upvotes: 0