仅在匹配阈值字节时才在地图中填充字符串值 [英] Populate string value in a map only if matches the threshold bytes

查看:177
本文介绍了仅在匹配阈值字节时才在地图中填充字符串值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个任务列表对象,我正在迭代并将每个任务对象附加到 StringBuilder 后跟新行如下所示。现在,我将继续在同一个字符串构建器中追加任务对象,直到达到60000字节的大小限制。一旦达到限制,我将把这个字符串填充为map中的值,key将是带有增量索引的文件名。然后我将重置字符串构建器和其他东西并再次重复此过程。

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.

所以如果我有一个很大的任务对象,然后我将拆分成多个字符串对象,其大小应始终小于60000字节。

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.

我得到了下面的代码,但我总是看到地图中的值有大小大于60000字节。我做错了什么?此外,我在两个不同的地方填充 HashMap - 一个达到限制,另一个如果未达到限制。

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);
  }

注意:如果每个Task对象超过 60000字节,然后我会立即删除该对象并转到下一个条目。但实际上,它不会发生。

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.

更新:

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;
}

这篇关于仅在匹配阈值字节时才在地图中填充字符串值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆