I have a tasks
list object which I am iterating and appending each task object into StringBuilder
followed by new line as shown below. Now I will keep appending task object in same string builder until it reaches a size limit of 60000 bytes. Once it reaches the limit, I will populate this string as a value in the map and key will be file name with incremental index. And then I will reset string builder and other thing and repeat this process again.
So if I have a big tasks
object, then I will split into multiple string object whose size should always be less than 60000 bytes.
I got below code but I always see value in the map has size greater than 60000 bytes. Anything wrong I am doing? Also I am populating into HashMap
at two different places - one if limit is reached and other is if limit is not reached.
public void populate(final List<Task> tasks) {
Map<String, String> holder = new HashMap<>();
int size = 0;
int index = 0;
StringBuilder sb = new StringBuilder();
for (Task task : tasks) {
sb.append(task).append(System.getProperty("line.separator"));
size = sb.toString().getBytes(StandardCharsets.UTF_8).length;
if (size > 60000) {
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
index++;
sb = new StringBuilder();
size = 0;
}
}
// for cases where we don't reach the limit
if(sb.toString().length > 0) {
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
}
System.out.println(holder);
}
Note: If each Task object is more than 60000 bytes
, then I will drop that object right away and move to next entry. But in real, its not gonna happen.
Update:
public void populate(final List<Task> tasks, final long timestamp) {
Map<String, String> holder = new HashMap<>();
int size = 0;
int index = 0;
int nl = System.getProperty("line.separator").getBytes(StandardCharsets.UTF_8).length;
StringBuilder sb = new StringBuilder();
// new change
sb.append(timestamp).append(System.getProperty("line.separator"));
for (Task task : tasks) {
int ts = String.valueOf(task).getBytes(StandardCharsets.UTF_8).length;
if (size + ts + nl > 60000) {
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
index++;
sb = new StringBuilder();
// new change
sb.append(timestamp).append(System.getProperty("line.separator"));
size = 0;
}
sb.append(task).append(System.getProperty("line.separator"));
size += ts + nl;
}
// for cases where we don't reach the limit
if (size > 0) { // size can only be 0 if you have 0 tasks
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
}
System.out.println(holder);
}
The reason why it is not working was already mentioned by other answers (you add after it already exceeded the limit). But I think none of the implementations is correct so far, not only because the size of the newline was ommitted.
public Map<String, String> populate(final List<Task> tasks) {
Map<String, String> holder = new HashMap<>();
if (tasks.size() == 0)
return holder;
int index = 0;
int nl = System.getProperty("line.separator").getBytes(StandardCharsets.UTF_8).length;
StringBuilder sb = new StringBuilder();
sb.append(System.currentTimeMillis()).append(System.getProperty("line.separator"));
int size = sb.toString().getBytes(StandardCharsets.UTF_8).length;
for (Task task : tasks) {
int ts = String.valueOf(task).getBytes(StandardCharsets.UTF_8).length;
if (size + ts + nl > 60000) {
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
index++;
sb = new StringBuilder();
sb.append(System.currentTimeMillis()).append(System.getProperty("line.separator"));
size = sb.toString().getBytes(StandardCharsets.UTF_8).length;
}
sb.append(task).append(System.getProperty("line.separator"));
size += ts + nl;
}
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
return holder;
}
I tried out your code to be sure of the solution. You need to try to check the next size before actually adding the new task's value to SB. I modified the code to reflect this solution. Could you try this out and tell us if it worked for you or not ?
public void populate(final List<Task> tasks) {
Map<String, String> holder = new HashMap<>();
int size = 0;
int index = 0;
int lengthTask = 0;
int lengthSb = 0;
StringBuilder sb = new StringBuilder();
for (Task task : tasks) {
lengthTask = task.toString().getBytes(StandardCharsets.UTF_8).length;
lengthSb = sb.toString().getBytes(StandardCharsets.UTF_8).length;
if (size + lengthTask + lengthSb > 60000) {
System.out.println("last added size "+size);
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
index++;
sb = new StringBuilder();
size = 0;
}
sb.append(task).append(System.getProperty("line.separator"));
size += sb.toString().getBytes(StandardCharsets.UTF_8).length;
System.out.println("size "+size);
}
// for cases where we don't reach the limit
String fileName = "tasks_info_" + index + ".txt";
holder.put(fileName, sb.toString());
System.out.println(holder);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With