Java 静态字符串或静态 StringBuilder
Java Static String or Static StringBuilder
在我的 Android 项目中,我有一个名为 Question
的单例 class,当应用程序处于 运行 时,它将被使用 90%。 class 包含两个名为 question 和 answer 的静态 String
变量,因为新实例会使用不同的 question 和 answer 字符串重复调用,因此每次都会创建一个新的 String
对象。我正在考虑将 String
变量更改为 StringBuilder
并每次都替换内容。
这是带有 String
个变量的代码:
public class Question {
private static Question mQuestionClass = null;
private static String mQuestion = "";
private static String mAnswer = "";
private Question() {
}
public static Question getQuestionInstance(String question, String answer) {
if (mQuestionClass == null) {
mQuestionClass = new Question();
}
mQuestion = question;
mAnswer = answer;
return mQuestionClass;
}
}
这是带有 StringBuilder
个变量的代码:
public class Questiontwo {
private static Questiontwo mQ2 = null;
private static StringBuilder mQ = null;
private static StringBuilder mA = null;
private Questiontwo() {
}
public static Questiontwo newInstance(String q, String a) {
if (mQ2 == null) {
mQ2 = new Questiontwo();
}
if (mQ == null) {
mQ = new StringBuilder(q);
}
mQ = mQ.replace(0, mQ.length(), q);
if (mA == null) {
mA = new StringBuilder(a);
}
mA = mA.replace(0, mA.length(), a);
return mQ2;
}
}
我应该选择哪一个使用尽可能少的内存?
class StringBuilder
在需要修改字符序列的内容时很有用。
来自 javadoc:
The principal operations on a StringBuilder are the append and insert
methods
StringBuilder 对于使用 +
或 concat()
方法替换字符串之间的串联序列非常有用。
如果您需要用另一个字符串替换一个字符串的全部内容StringBuilder
不是正确的选择。事实上,我想您会将带有新问题的字符串传递给 StringBuilder 以更改其内容。如果您这样做,您已经创建了新字符串(带有新问题)。
因此,在此上下文中使用 StringBuilder 会增加一些内存使用量和一些 cpu 计算,而不是将其删除。
首先让我们讨论两件事:
一:为什么把一个字符串赋值给另一个会消耗更多的内存
二:StringBuilder是如何解决这个问题的
一:
例如,当您有一个字符串 String a
并为其分配一个值时,例如 a = "Hello"
java 将做的是在内存中创建一个新字符串,并将 指向它。因此,每次您将值更改为 a = "good"
时,它都会在内存中创建另一个字符串,并且 a
指针将从 hello
更改为 good
并且 hello
仍然存在在内存中但是它是可访问的,因为没有人指向它。
二:
字符串生成器改为修改旧字符串并将其更改为新字符串,因此它会消耗更少的内存。当你想修改一个字符串时,它很有用。
我想看看 this 也会对你有所帮助。
在这两种情况下,您的设计似乎都有点缺陷。您正在使用静态变量并在构造函数中对其进行初始化。这似乎违反直觉 - 因为如果您尝试创建 Question
的多个实例,静态变量的值将由最后创建的实例设置。
我建议只使用简单的 class
public class Question {
private String mQuestion = "";
private String mAnswer = "";
public Question(String question, String answer) {
mQuestion = question;
mAnswer = answer;
}
}
只需创建 Question
的实例并像使用常规 Java 对象一样使用它们,而不是使用静态变量创建单例并在此过程中引入意外错误。让 Android 对不再使用的对象进行垃圾回收。
Question q = new Question("What is capital of India?", "New Delhi");
在我的 Android 项目中,我有一个名为 Question
的单例 class,当应用程序处于 运行 时,它将被使用 90%。 class 包含两个名为 question 和 answer 的静态 String
变量,因为新实例会使用不同的 question 和 answer 字符串重复调用,因此每次都会创建一个新的 String
对象。我正在考虑将 String
变量更改为 StringBuilder
并每次都替换内容。
这是带有 String
个变量的代码:
public class Question {
private static Question mQuestionClass = null;
private static String mQuestion = "";
private static String mAnswer = "";
private Question() {
}
public static Question getQuestionInstance(String question, String answer) {
if (mQuestionClass == null) {
mQuestionClass = new Question();
}
mQuestion = question;
mAnswer = answer;
return mQuestionClass;
}
}
这是带有 StringBuilder
个变量的代码:
public class Questiontwo {
private static Questiontwo mQ2 = null;
private static StringBuilder mQ = null;
private static StringBuilder mA = null;
private Questiontwo() {
}
public static Questiontwo newInstance(String q, String a) {
if (mQ2 == null) {
mQ2 = new Questiontwo();
}
if (mQ == null) {
mQ = new StringBuilder(q);
}
mQ = mQ.replace(0, mQ.length(), q);
if (mA == null) {
mA = new StringBuilder(a);
}
mA = mA.replace(0, mA.length(), a);
return mQ2;
}
}
我应该选择哪一个使用尽可能少的内存?
class StringBuilder
在需要修改字符序列的内容时很有用。
来自 javadoc:
The principal operations on a StringBuilder are the append and insert methods
StringBuilder 对于使用 +
或 concat()
方法替换字符串之间的串联序列非常有用。
如果您需要用另一个字符串替换一个字符串的全部内容StringBuilder
不是正确的选择。事实上,我想您会将带有新问题的字符串传递给 StringBuilder 以更改其内容。如果您这样做,您已经创建了新字符串(带有新问题)。
因此,在此上下文中使用 StringBuilder 会增加一些内存使用量和一些 cpu 计算,而不是将其删除。
首先让我们讨论两件事:
一:为什么把一个字符串赋值给另一个会消耗更多的内存
二:StringBuilder是如何解决这个问题的
一:
例如,当您有一个字符串 String a
并为其分配一个值时,例如 a = "Hello"
java 将做的是在内存中创建一个新字符串,并将 指向它。因此,每次您将值更改为 a = "good"
时,它都会在内存中创建另一个字符串,并且 a
指针将从 hello
更改为 good
并且 hello
仍然存在在内存中但是它是可访问的,因为没有人指向它。
二:
字符串生成器改为修改旧字符串并将其更改为新字符串,因此它会消耗更少的内存。当你想修改一个字符串时,它很有用。
我想看看 this 也会对你有所帮助。
在这两种情况下,您的设计似乎都有点缺陷。您正在使用静态变量并在构造函数中对其进行初始化。这似乎违反直觉 - 因为如果您尝试创建 Question
的多个实例,静态变量的值将由最后创建的实例设置。
我建议只使用简单的 class
public class Question {
private String mQuestion = "";
private String mAnswer = "";
public Question(String question, String answer) {
mQuestion = question;
mAnswer = answer;
}
}
只需创建 Question
的实例并像使用常规 Java 对象一样使用它们,而不是使用静态变量创建单例并在此过程中引入意外错误。让 Android 对不再使用的对象进行垃圾回收。
Question q = new Question("What is capital of India?", "New Delhi");