Java Char数组vs String:哪个更适合存储一组字母

Java Char数组vs String:哪个更适合存储一组字母,java,performance,coding-style,constants,Java,Performance,Coding Style,Constants,我需要存储一个恒定的4类代码字母。我可以做到: static final String CODE_LETTERS = "TRWAG"; 或 之后,我可以通过两种方式获得其中一个字符: final char codeLetter = CODE_LETTERS.charAt(index); 或 最好的办法是什么?。请记住更正、性能等。除非您要连续提取数百万次字符,否则您无需担心性能。两者都不正确,但由于您将单独处理字符,我个人将使用字符[]。也就是说,即使可以测量,这对性能的影响也可以忽略不计。

我需要存储一个恒定的4类代码字母。我可以做到:

static final String CODE_LETTERS = "TRWAG";

之后,我可以通过两种方式获得其中一个字符:

final char codeLetter = CODE_LETTERS.charAt(index);


最好的办法是什么?。请记住更正、性能等。

除非您要连续提取数百万次字符,否则您无需担心性能。

两者都不正确,但由于您将单独处理
字符,我个人将使用
字符[]
。也就是说,即使可以测量,这对性能的影响也可以忽略不计。

这几乎可以肯定是过早的优化。如果需要将字符数组用于其他方法,则使用字符数组在性能上节省的内容可能会丢失可读性,因为接受
字符串
比接受
char[]

更为规范,因为字符串使用char[]保存字母,真正的答案是char[]更快。当你怀疑的时候,看看源代码,字符串中没有魔法,它只是像任何其他类一样使用int和char[]这样的原语


你真的不应该关心像这样琐碎的事情。在一个程序中会发生更多的事情,担心单个字符串是否比使用字符数组快。

在这种情况下,性能是无关紧要的。如果它真的应该是常量,那么就不能使用
char[]
方法。考虑:

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
  }
}

String
的含义确实与一组
char
匹配。因此,
char[]
作为一个实现,虽然不是意义集,但不会添加
String
的额外意义。另外,您可能会在
字符串中找到有用的方法。第三方面,还有一些有用的方法,如[binarySearch][2]

也许您想做的是为一组
char
引入一个抽象,它的实现可能会有所不同,可以使用
String
作为可能工作的最简单的方法,线性扫描
char[]
(如果扫描不太远,则快速)、二进制搜索、位集。稀疏位集、散列、洪水过滤等


[2] :,int,int,char)

只有在探查器下才能看到字符串和字符数组之间的性能差异,这只是因为探查器会做错误的事情。现代JVM(JDk 6+)将在JVM确定这足够热以进行优化后,为两个访问生成相同的代码

回答你的问题;如果您使用的是Java5,请使用枚举;如果您使用的是Java5之前的版本,请使用

它将使您的代码更具可读性,因为您不需要在某个地方跟踪偏移量,您只需使用枚举即可。此外,它将更快,因为您将能够执行以下操作:


  final char codeLetter = enum.getCodeLetter(); 

看起来你应该考虑使用<强> EnUM<强>。


请参见

字符串是不可变的,char[]不是。如果将其定义为类中的公共“常量”,则字符串是真正的常量

例如,如果您有:

public class MyClass { 
    public static final char[] CODE_LETTERS = {'h', 'e', 'l', 'l', 'o'};
    ....
}
我可以鬼鬼祟祟地这么做:

MyClass.CODE_LETTERS[0] = 'Q';
砰,我更改了你的“常数”的值

final
关键字只影响对数组的引用,不适用于数组元素。我一直在
集合中看到类似的错误。unmodifiableList()
,人们认为这可以保护他们的列表,但客户端代码仍然可以访问和修改列表元素


所以要回答你的问题,请使用字符串。

有趣的是,我昨天刚刚写了一篇关于这个的文章。您需要一个围绕char[]的专门类。我的类是一种保持不变字符集的轻量级方法,并为搜索之类的事情提供了高效的方法。它是开源的。

我的想法正是如此。严肃地说:过早的优化是万恶之源。但同样地,我们不应该过早地悲观。对于固定长度的不可变字符串,char数组总是比equiavlent std::string对象更快,内存开销更少。这很可能是一种需要多次执行的操作。如果这是
java.lang.String
实现中的一个新方法会怎样?看起来像5个字母:)谁说性能无关?很多人在表现上花费了很多精力。当然,实现可以做一些不好的事情,但是如果表示是本地化的,我们可以说“那么不要这样做”。我的意思是这不是性能问题,因为char[]版本甚至不能按预期工作。让我们集中精力纠正这种情况下的明显错误:过早优化和使用数组作为常量。我在这里提到它是为了避免让读者太困惑。在不知道它的用途的情况下,这不是一个好的建议。如果他要将字符与其他字符进行比较,那么枚举就没有意义。没有迹象表明枚举是他想要的。如果他打算将字符用作某个地方的字符,那么将它们存储为枚举是没有意义的。如果枚举值为t、R、W、A、G,则可以使用toString()。是的,但当字符串在语义上表示用作字符串而不是字符数组时,则应使用字符串。在Java中使用char[]只有在您想处理单个字符项或需要频繁替换数组位置时才有意义。您的类会根据构造对其字符进行排序,因此它不会真正回答他的问题,但我喜欢该类背后的想法。如果我能自己+1你的博客帖子,我会的。@ahcox,谢谢你的好话。我已经在我的博客网站上添加了Facebook的“喜欢”功能,所以请随意试用
public class MyClass { 
    public static final char[] CODE_LETTERS = {'h', 'e', 'l', 'l', 'o'};
    ....
}
MyClass.CODE_LETTERS[0] = 'Q';