【问题标题】:Difference between String, String Builders, Character Arrays and Arraylist [closed]字符串、字符串生成器、字符数组和 Arraylist 之间的区别 [关闭]
【发布时间】:2014-05-20 20:33:46
【问题描述】:

字符串是不可变的。字符串生成器不是,因此您可以在末尾附加字符。字符串是字符数组,如果我没看错的话,为什么我们分开使用字符数组和字符串分开,我们真的需要使用字符数组吗?

其次,有字符数组,然后是 Arraylist。数组列表包含完整的对象?其实我有点迷茫。

String cat = "c" + "a" + "t";
cat = cat + cat;

StringBuilder sb = new StringBuilder();
sb.append(city);
sb.append(", ");
sb.append(state);
sb.toString();

Char apple[5]={'a','p','p','l','e'};

Arraylist<MyCar>obj = new Arraylist<MyCar>();

哪个应该用在什么地方?

【问题讨论】:

  • 字符串不是java中的字符数组,字符串是对象。当您在内部将字符附加到字符串时,JVM 使用 StringBuffer。
  • 字符串是对象吗?对象类型?
  • @user3510103 String 类型的对象。
  • 我们在 java 中有 String 类,你可以将 String 创建为 String s=new String("abcd");
  • 字符数组是连续的内存位置,而Arraylist使用链表数据结构!

标签: java arrays string arraylist


【解决方案1】:

String 是包含底层 char 数组的不可变对象。

在第 2 行中,您丢弃在第 1 行中创建的字符串并创建一个新字符串。
字符串生成器避免为每个单独的子字符串创建新的字符串对象。

数组和Arraylist都可以包含对象,主要区别在于Arraylist可以增长,数组不能。第二个区别是 Arraylist 真的是一个 List...

【讨论】:

  • 这意味着arraylist和arrays之间的唯一区别是arraylists是动态的,而后者是静态的
  • static 有不同的内涵,所以我不会这样称呼数组。
  • 我喜欢你的回答。我该如何投票?该网站不允许我这样做。它说我需要 15 声望
【解决方案2】:

String使用char[]String 不是char[],就像ArrayList&lt;String&gt; 不是String[]

ArrayList 类型是一个动态数据结构。这意味着它可以根据需要增长。 Array静态的,这意味着它的尺寸在其生命周期内不会改变。

【讨论】:

  • 我喜欢你的回答。我该如何投票?该网站不允许我这样做。它说我需要 15 声望
【解决方案3】:

通常String用于普通的基于字符串的需求,当一个String就足够了。

String Builder 在您想要操作和使用字符串时使用。

字符数组用于轻松遍历每个字符

ArrayList 是一个集合。用它来保存特定类型的对象。

【讨论】:

  • 我喜欢你的回答。我该如何投票?该网站不允许我这样做。它说我需要 15 声望
  • @user3510103 这意味着当你获得 15 个声望(现在你有 12 个)时,你将能够投票。这是防止机器人投票的简单安全机制。在这里您可以找到有关如何获得(或失去)声誉stackoverflow.com/help/whats-reputation 的简单说明
  • 非常感谢 Pshemo
【解决方案4】:

这个解释最好:在string和stringBuilder之间 参考:Correct way to use StringBuilder

请注意,目标(通常)是减少内存流失而不是使用的总内存,以使垃圾收集器的工作更轻松。

Will that take memory equal to using String like below?

不,它会导致比您引用的直接连接更多的内存流失。 (直到/除非 JVM 优化器发现代码中的显式 StringBuilder 是不必要的,如果可以的话,会对其进行优化。)

如果该代码的作者想要使用 StringBuilder(有支持,但也有反对;请参阅此答案末尾的注释),最好正确执行(这里我假设实际上没有引号id2 和 table):

StringBuilder sb = new StringBuilder(some_appropriate_size);
sb.append("select id1, ");
sb.append(id2);
sb.append(" from ");
sb.append(table);
return sb.toString();

请注意,我在 StringBuilder 构造函数中列出了 some_appropriate_size,以便它开始时有足够的容量来容纳我们要附加的全部内容。如果您不指定一个,则使用的默认大小是 16 个字符,这通常太小,导致 StringBuilder 必须进行重新分配以使其更大(IIRC,在 Sun/Oracle JDK 中,它会增加一倍 [或更多,如果它知道每次空间不足时需要更多来满足特定的附加]。

您可能听说过,如果使用 Sun/Oracle 编译器进行编译,字符串连接将使用 StringBuilder。这是真的,它将使用一个 StringBuilder 来进行整体表达式。但它将使用默认构造函数,这意味着在大多数情况下,它必须进行重新分配。不过,它更容易阅读。请注意,这不适用于一系列串联。例如,这使用了一个 StringBuilder:

返回“前缀”+变量1+“中间”+变量2+“结束”;

大致翻译为:

StringBuilder tmp = new StringBuilder(); // Using default 16 character size
tmp.append("prefix ");
tmp.append(variable1);
tmp.append(" middle ");
tmp.append(variable2);
tmp.append(" end");
return tmp.toString();

所以没关系,虽然默认构造函数和后续的重新分配并不理想,但很有可能它已经足够好了——并且串联起来更具可读性。

但这仅适用于单个表达式。为此使用了多个 StringBuilder:

String s;
s = "prefix ";
s += variable1;
s += " middle ";
s += variable2;
s += " end";
return s;

最终变成这样:

String s;
StringBuilder tmp;
s = "prefix ";
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable1);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" middle ");
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable2);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" end");
s = tmp.toString();
return s;

...这很丑。

但重要的是要记住,除了极少数情况外,它并不重要,并且除非出现特定的性能问题,否则优先考虑可读性(增强可维护性)。

【讨论】:

  • 哇,这是最好的答案,我怎么能赞成这个答案?我需要 15 个代表 :(。最好的一个,它解释了一切。非常感谢 ami。
  • 如果它有帮助我很高兴,你可以稍后投票:)
  • 上帝之母你真的全力以赴@ami +1
  • 加一。很好地解释了@AmiPatel
猜你喜欢
  • 2017-01-29
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
相关资源
最近更新 更多