views:

1399

answers:

9

I need to store in a constant class 4 letter of a code. I can do:

static final String CODE_LETTERS = "TRWAG";

or

static final char[] CODE_LETTERS = {'T', 'R', 'W', 'A', 'G'};

After, I can obtain one of that characters in two ways:

final char codeLetter = CODE_LETTERS.charAt(index);

or

final char codeLetter = CODE_LETTERS[index];

what is the best way?. Please take in mind correction, performance, etc.

+4  A: 

Unless you are going to fetch the character several million times in a row, you don't need to bother about the performance.

Fredrik Mörk
My thoughts exactly. Seriously: *Premature optimization is the root of all evil.*
Cloud
But equally one should not pessimize prematurely. For a fixed length immutable string a char array will always be quicker and have less memory overhead than the equiavlent std::string object.
Visage
It may well be the sort of thing that gets done lots of times. What if this was a new method in the implementation of `java.lang.String`?
Tom Hawtin - tackline
+8  A: 

Neither is incorrect, but since you're going to be dealing with the chars individually I'd personally use the char []. That said, the impact this will have on performance is going to be negligible if even measurable.

Eoin Campbell
+2  A: 

This is almost certainly a premature optimization. Whatever you save in performance by using a character array may be lost in readability if you need to give it to other methods, since it's more canonical to accept a String rather than a char[].

John Feminella
+1  A: 

Since a String uses a char[] to hold your letters the true answer is the char[] is faster. When in doubt look at the source, theres no magic in String, it just uses primitives like int and char[] just like any other class.

You really shouldnt care about something as trivial as this. A hell of a lot more happens within a program, that worrying about whether a single String is faster than using a char array.

mP
+3  A: 

Performance is irrelevant in this case. If it's really supposed to be constant, you can't use the char[] approach. Consider:

public class Test
{
  static final char[] CODE_LETTERS = {'T', 'R', 'W', 'A', 'G'};

  public static void main(String[] args) throws Exception
  {
    System.out.println(CODE_LETTERS[0]); // T
    CODE_LETTERS[0] = 'x';
    System.out.println(CODE_LETTERS[0]); // x
  }
}
Alan Moore
Who says performance is irrelevant? Lots of people spend a lot of effort on performance. Of course the implementation can do naughty things, but if the representation is localised we can just say "don't do that then".
Tom Hawtin - tackline
I meant it's not a question of performance, because the char[] version doesn't even work as intended. Let's concentrate on correcting the obvious errors IN THIS CASE: premature optimization, and using an array as a constant.
Alan Moore
I edited my answer after the exchange above and added the "in this case" qualifier. I'm mentioning it here to avoid confusing readers too badly.
Alan Moore
+1  A: 

The meaning of String does really match a set of char. So char[] as an implementation, although not meaning set, would not add the extra meaning of String. OTOH, you might find useful method in String. On the third hand, java.util.Arrays also has useful methods such as [binarySearch][2].

Perhaps what you want to do is introduce an abstraction for a set of char which might vary implementation between using String as the simplest that could possibly work, linear scanning of a char[] (fast if you don't scan very far), binary search, bit set. sparse bit set, hashed, flood filtered, etc.

[2]: http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#binarySearch(char[], int, int, char)

Tom Hawtin - tackline
+1  A: 

The only time that you will see a performance difference between the String and the character array is going to be under a profiler, and then only because the profiler will do the wrong thing. Modern JVMS (JDk 6+) will generate the same code for the two accesses once the JVM decides that this is hot enough to optimise.

To answer your question though; If you are using Java 5, use enumerations, if you are using something prior to Java5, use the Java enumeration Pattern.

It will make your code more readable, as you won't need to keep track of the offsets somewhere, you can just use the enumeration. Additionally, it will be faster, since you will be able to do something like:


  final char codeLetter = enum.getCodeLetter(); 
Paul Wagland
There's no indication that enum is what he wants. If he is going to be using the characters as characters somewhere then it doesn't make sense to store them as enums.
DJClayworth
If the enum values are T, R, W, A, G then toString() could be used.
Peter Lawrey
+1  A: 

Looks like your should consider using an enum. See Enum Types

crowne
Without knowing what the use is that's not a good suggestion. If he is going to compare the character against other characters then an enum doesn't make sense.
DJClayworth
A: 

Strings are immutable, char[] is not. If you are defining this as a public "constant" in a class then String is the real constant.

For example if you have this:

public class MyClass { 
    public static final char[] CODE_LETTERS = {'h', 'e', 'l', 'l', 'o'};
    ....
}

I can be all sneaky and do this:

MyClass.CODE_LETTERS[0] = 'Q';

Bam, I've changed the value of your "constant".

The final keyword only affects the reference to the array, it does not apply to the array elements. I see a similar mistake all the time with Collections.unmodifiableList(), people think its protecting their list but client code can still access and modify the list elements.

So to answer your question, use the String.

Mike Kucera