Reputation: 316
I have a loop thats constantly setting new values to a few string and looking into it, i thought that i could improve it. At first it was easy (this is how it actually looks) but i am looking for a way to avoid doing that lot of "ToString" and then resetting that string to "".
private void obtenerProfCita(JSONArray catalogoDatos) {
String areaConsumer = "";
String resourceConsumer = "";
String activityConsumerid = "";
for(int i = 0; i < catalogoDatos.length(); i++) {
areaConsumer = catalogoDatos.getJSONObject(i).get("area_consumerid").toString();
resourceConsumer = catalogoDatos.getJSONObject(i).get("resource_consumerid").toString();
activityConsumerid = catalogoDatos.getJSONObject(i).get("activity_consumerid").toString();
if(StringUtils.isNotBlank(areaConsumer) && StringUtils.isNotBlank(resourceConsumer) && StringUtils.isNotBlank(activityConsumerid)) {
log.error("REFERENCIA TUOTEMPO:\nModulo: " + i + "\nCONSUL: " + areaConsumer + "\nIDPROF: " + resourceConsumer);
TuotempoDAO.guardarActivityId(catalogoDatos.getJSONObject(i));//Guardar en BBDD el Activity_ID
}
areaConsumer = "";
resourceConsumer = "";
}
}
As you can see, is a basic for loop but taking in account that the JSONArray is quite big, i was looking for a way to use StringBuilders or StringBuffers and avoid the "ToStrings" in the JSON array.
Actual code with stringBuilders:
private void obtenerProfCita(JSONArray catalogoDatos) {
StringBuilder areaConsumer = new StringBuilder();
StringBuilder resourceConsumer = new StringBuilder();
StringBuilder activityConsumerid = new StringBuilder();
for(int i = 0; i < catalogoDatos.length(); i++) {
areaConsumer.append(catalogoDatos.getJSONObject(i).get("area_consumerid").toString());
resourceConsumer.append(catalogoDatos.getJSONObject(i).get("resource_consumerid").toString());
activityConsumerid.append(catalogoDatos.getJSONObject(i).get("activity_consumerid").toString());
if(StringUtils.isNotBlank(areaConsumer) && StringUtils.isNotBlank(resourceConsumer) && StringUtils.isNotBlank(activityConsumerid)) {
log.error("REFERENCIA TUOTEMPO:\nModulo: " + i + "\nCONSUL: " + areaConsumer + "\nIDPROF: " + resourceConsumer);
TuotempoDAO.guardarActivityId(catalogoDatos.getJSONObject(i));//Guardar en BBDD el Activity_ID
}
areaConsumer.setLength(0);
resourceConsumer.setLength(0);
}
}
Also i have doubts about how efficient is to use StringBuilder instead of String, if someone could explain it to me it would be great.
EDIT. Thanks to OH GOD SPIDERS below, i have improved a little my code. here it´s how it looks right now:
private void obtenerProfCita(JSONArray catalogoDatos) {
StringBuilder areaConsumer = new StringBuilder();
StringBuilder resourceConsumer = new StringBuilder();
StringBuilder activityConsumerid = new StringBuilder();
for(int i = 0; i < catalogoDatos.length(); i++) {
areaConsumer.append(catalogoDatos.getJSONObject(i).get("area_consumerid"));
resourceConsumer.append(catalogoDatos.getJSONObject(i).get("resource_consumerid"));
activityConsumerid.append(catalogoDatos.getJSONObject(i).get("activity_consumerid"));
if (StringUtils.isNotBlank(areaConsumer)
&& StringUtils.isNotBlank(resourceConsumer)
&& StringUtils.isNotBlank(activityConsumerid)) {
log.error("REFERENCIA TUOTEMPO:\nModulo: " + i + "\nCONSUL: " + areaConsumer + "\nIDPROF: " + resourceConsumer);
TuotempoDAO.guardarActivityId(catalogoDatos.getJSONObject(i));//Guardar en BBDD el Activity_ID
}
areaConsumer.setLength(0);
resourceConsumer.setLength(0);
activityConsumerid.setLength(0);
}
}
Any help is appreciatted
EDIT2:
Thank you for all the help, i will modify my code taken in account the last comment and answers.
Upvotes: 0
Views: 432
Reputation: 11
stringbuilder create one object but for '+',every time you use will create a new Stringbuilder object and use tostring() once,as the byteCodes show
for test1,loop body contains: one StringBuilder Object init,two append method,one tostring method
for test2,loop body contains: one append method
public class Test6 {
String test1(){
String a = "";
for (int i = 0; i < 10; i++) {
a += "a";
}
return a;
}
String test2(){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
sb.append("a");
}
return sb.toString();
}
}
test1
0 ldc #2
2 astore_1
3 iconst_0
4 istore_2
5 iload_2
6 bipush 10
8 if_icmpge 37 (+29)
11 new #3 <java/lang/StringBuilder>
14 dup
15 invokespecial #4 <java/lang/StringBuilder.<init> : ()V>
18 aload_1
19 invokevirtual #5 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
22 ldc #6 <a>
24 invokevirtual #5 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
27 invokevirtual #7 <java/lang/StringBuilder.toString : ()Ljava/lang/String;>
30 astore_1
31 iinc 2 by 1
34 goto 5 (-29)
37 aload_1
38 areturn
test2
0 new #3 <java/lang/StringBuilder>
3 dup
4 invokespecial #4 <java/lang/StringBuilder.<init> : ()V>
7 astore_1
8 iconst_0
9 istore_2
10 iload_2
11 bipush 10
13 if_icmpge 29 (+16)
16 aload_1
17 ldc #6 <a>
19 invokevirtual #5 <java/lang/StringBuilder.append : (Ljava/lang/String;)Ljava/lang/StringBuilder;>
22 pop
23 iinc 2 by 1
26 goto 10 (-16)
29 aload_1
30 invokevirtual #7 <java/lang/StringBuilder.toString : ()Ljava/lang/String;>
33 areturn
Upvotes: 1
Reputation: 21435
Your loop is not appending to the strings and therefore using StringBuilder
gives no performance improvements.
I would only do two things:
catalogoDatos.getJSONObject(i)
once and store that reference in a local variableThis gives the following code:
private void obtenerProfCita(JSONArray catalogoDatos) {
for (int i = 0; i < catalogoDatos.length(); i++) {
JSONObject o = catalogoDatos.getJSONObject(i);
String areaConsumer = o.get("area_consumerid").toString();
String resourceConsumer = o.get("resource_consumerid").toString();
String activityConsumerid = o.get("activity_consumerid").toString();
if (StringUtils.isNotBlank(areaConsumer) && StringUtils.isNotBlank(resourceConsumer) && StringUtils.isNotBlank(activityConsumerid)) {
log.error("REFERENCIA TUOTEMPO:\nModulo: " + i + "\nCONSUL: " + areaConsumer + "\nIDPROF: " + resourceConsumer);
TuotempoDAO.guardarActivityId(o);//Guardar en BBDD el Activity_ID
}
}
}
About the idea that StringBuilder.append()
somehow works around the need for toString()
:
What do you think how StringBuilder.append()
does append the string representation of an object?
Great surprise: it uses toString()
internally.
Actually, if you look at the internals of StringBuilder.append(Object)
:
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
it calls String.valueOf(obj)
which is
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Effectively the only difference between
stringBuilder.append(obj);
and
stringBuilder.append(obj.toString());
is that first version correctly handles the case where obj
is null whereas in the second case it will throw a NullPointerException
.
Upvotes: 3
Reputation: 8163
The difference, when concatenating lots of Strings in a loop is that:
Doesn't matter much for small amounts of Strings, but if your array is big it should be noticeable.
Upvotes: 3