Reputation: 3564
There are already some posts looks relative to this, I went through them, but those not solved my problem:
I have a method and some logic, I have to do code optimize using streams.
My method is: (here I am trying to print the emails in a formatted way)
public static StringBuilder printEmailsListFormat(ArrayList<String> a) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < a.size(); i++) {
if (i % 3 ==0)
{
sb.append(String.format("%-45s", a.get(i)));
sb.append("\n");
}
else
sb.append(String.format("%-45s", a.get(i)));
}
return sb;
}
I have to optimize this code.
Upvotes: 1
Views: 769
Reputation: 44110
This is about the best you can do. It's pretty ugly, because streams are not aware of the list indices. It is not a very good candidate for converting to use streams.
public static StringBuilder printEmailsListFormat(ArrayList<String> a) {
return IntStream.range(0, a.size())
.mapToObj(i -> {
String format = "%-45s";
if (i % 3 == 0) format += "\n";
return String.format(format, a.get(i));
})
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
}
Upvotes: 1
Reputation: 298123
If you want to optimize your code, you should not switch to the Stream API. Instead, change it to use a single Formatter
, instead of one for each element (hidden inside String.format
) and avoid the temporary strings created by String.format
:
public static StringBuilder printEmailsListFormat(List<String> a) {
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
for(int i = 0; i < a.size(); i++) {
formatter.format("%-45s", a.get(i));
if(i % 3 ==0) sb.append("\n");
}
return sb;
}
Given the simplicity of the format in this specific case, you may even eliminate the Formatter
completely:
static final String EMPTY_CELL = String.format("%45s", ""); //JDK11: " ".repeat(45);
public static StringBuilder printEmailsListFormat(List<String> a) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < a.size(); i++) {
String s = a.get(i);
sb.append(s);
if(s.length() < EMPTY_CELL.length())
sb.append(EMPTY_CELL, s.length(), EMPTY_CELL.length());
if(i % 3 ==0) sb.append("\n");
}
return sb;
}
Upvotes: 2
Reputation: 154
You can only parallelize and therefore speed up the formatting of the strings, but not the concatenation of the formatted parts, since they must be in order.
You could also concatenate the formatted parts via stream, but a for-loop is faster. So you would get:
// just some example values
ArrayList<String> a = new ArrayList(Arrays.asList("string1", "string2", "string3", "string4", "string5"));
// formatting them in parallel
List<String> formatted = a.parallelStream().map(s -> String.format("%-45s", s)).collect(Collectors.toList());
// concatenating them in order
StringBuilder sb = new StringBuilder();
for (ListIterator<String> i = formatted.listIterator(); i.hasNext();) {
sb.append(i.next());
if (i.previousIndex() % 3 == 0) {
sb.append("\n");
}
}
System.out.println("output: " + sb);
The output is:
output: string1
string2 string3 string4
string5
Remark: consider using System.getProperty("line.separator") instead of "\n".
Upvotes: 0