首页 \ 问答 \ Map.clear()然后将地图添加到List(Map.clear() then add map to List)

Map.clear()然后将地图添加到List(Map.clear() then add map to List)

我尝试使用基于jdk1.6的 poi.jar来遍历一些excel2007数据 。但是当我发现一个奇怪的现象时,我遍历行(由HashMap ()存储),然后将行数据添加到java.util 。 ArrayList

并且启动下一个迭代器,我首先通过调用Map.clear()清除行数据,但是当再次调用ArrayList.add()方法时,此行数据将覆盖旧数据。

   Map<String, String> cellForRow = = new HashMap<String, String>();
   List<Map<String, String>> rowForSheet = new ArrayList<Map<String, String>>();
   for (int j = 0; j < sheet.getPhysicalNumberOfRows(); j++) {

                    row = sheet.getRow(j);
                    if (j == 0) {// the first row is title
                        titleRow = row;
                        continue;
                    }
                    if (row != null && titleRow.getPhysicalNumberOfCells() > 0) {
                        // cellForRow = new HashMap<String, String>();
                        cellForRow.clear();
                        for (int k = 0; k < titleRow.getPhysicalNumberOfCells(); k++) {// cell
                            cellForRow.put(getCellValue(titleRow.getCell(k)), getCellValue(row.getCell(k)));
                        }
                    }
                    rowForSheet.add(cellForRow);
                }

Next Snippets显示rowForSheet (List)的调试日志

[{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream}]

后来的数据会覆盖旧数据

你是否?


I try to traverse some excel2007 data by using poi.jar based on jdk1.6.But when I seem to find a strange phenomenon that when I traverse the row(stored by HashMap()) and then add the row data to java.util.ArrayList .

And starting the next iterator,I first clear the row data by invoking Map.clear(), but when again invoking the ArrayList.add() method,this row data is overridden the older data.

   Map<String, String> cellForRow = = new HashMap<String, String>();
   List<Map<String, String>> rowForSheet = new ArrayList<Map<String, String>>();
   for (int j = 0; j < sheet.getPhysicalNumberOfRows(); j++) {

                    row = sheet.getRow(j);
                    if (j == 0) {// the first row is title
                        titleRow = row;
                        continue;
                    }
                    if (row != null && titleRow.getPhysicalNumberOfCells() > 0) {
                        // cellForRow = new HashMap<String, String>();
                        cellForRow.clear();
                        for (int k = 0; k < titleRow.getPhysicalNumberOfCells(); k++) {// cell
                            cellForRow.put(getCellValue(titleRow.getCell(k)), getCellValue(row.getCell(k)));
                        }
                    }
                    rowForSheet.add(cellForRow);
                }

Next Snippets show the debug log for rowForSheet(List)

[{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream},
{ Up =Stream, Email=XXX,Down =Stream}]

the later data override the older data

Did you?


原文:https://stackoverflow.com/questions/40523285
更新时间:2022-04-20 16:04

最满意答案

正如我的评论中提到的,我强烈怀疑服务器关闭了通过putty建立的连接,因为您的程序存在问题。

但是这里有程序代码的几个问题。


最关键的问题是您是从两个线程同时访问两个全局变量。

需要保护并发访问。 为此,请声明两个互斥量,如下所示:

pthread_mutex_t mutex_read = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_time = PTHREAD_MUTEX_INITIALIZER;


void *readFromFile(void *myFile)
{
    ...

    {
      int result = pthread_mutex_lock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_lock(mutex_read) failed");
      }
    }

    read = 1;

    {
      int result = pthread_mutex_unlock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_unlock(mutex_read) failed");
      }
    }

    ...
}


void displayTimeLeft(void *arg)
{
    ...

    {
      int result = pthread_mutex_lock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_lock(mutex_time) failed");
      }
    }

    timeLeft= 1;

    {
      int result = pthread_mutex_unlock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_unlock(mutex_time) failed");
      }
    }

    ...

}

int main(void)
{
  ...

  while(1)
  {
    int bread = 0;
    int btimeLeft = 0;

    {
      int result = pthread_mutex_lock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_lock() failed");
      }
    }

    bread = (1 == read);

    {
      int result = pthread_mutex_unlock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_unlock() failed");
      }
    }

    {
      int result = pthread_mutex_lock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_lock() failed");
      }
    }

    btimeLeft = (1 == timeLEft);

    {
      int result = pthread_mutex_unlock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_unlock() failed");
      }
    }

    if (bread == 1)
    {

      pthread_cancel(thread2);
      pthread_cancel(thread1);
      break;
    }
    else if (btimeLeft == 1)
    {

      pthread_cancel(thread1);
      pthread_cancel(thread2);
      break;
    }
  }  
  ...

对于PThreads,thr threas函数需要声明为:

void * (*) (void *)

对于displayTimeLeft ,情况并非如此


当在“字符串”中扫描时,需要传递表示字符串的字符数组的第一个元素的地址。 所以这

scanf("%s", &answer);

应该是这个

scanf("%s", &answer[0]);

或这个

scanf("%s", answer);

代码错过了sleep()的原型,所以添加

#include <unistd.h>

完成此操作后,编译器会检测系统调用read()与代码声明的全局变量read之间的名称冲突。 这不好。 将read重命名为readit


最后并非最不重要的是,在他的回答中,嫌疑人有问题。 您滥用指向int的指针来存储一些时间值( int * time = 180 )。 不要那样做。

要修复这个,请执行以下操作:

int main(void)
{
  ...
  int time = 180;
  ...
  ret2 = pthread_create(&thread2, NULL, displayTimeLeft, &time);

并在displayTimeLeft执行:

 int time = *((int*) arg);

As mentioned in my comment I strongly doubt the server shuts down the connection established via putty because issues with your program.

However here are several issues with the program's code.


The ost critical issue is you are accessing the two global variable concurrently from two threads.

Concurrent access needs to be protected. To do so declare two mutexes like so:

pthread_mutex_t mutex_read = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_time = PTHREAD_MUTEX_INITIALIZER;


void *readFromFile(void *myFile)
{
    ...

    {
      int result = pthread_mutex_lock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_lock(mutex_read) failed");
      }
    }

    read = 1;

    {
      int result = pthread_mutex_unlock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_unlock(mutex_read) failed");
      }
    }

    ...
}


void displayTimeLeft(void *arg)
{
    ...

    {
      int result = pthread_mutex_lock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_lock(mutex_time) failed");
      }
    }

    timeLeft= 1;

    {
      int result = pthread_mutex_unlock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_unlock(mutex_time) failed");
      }
    }

    ...

}

int main(void)
{
  ...

  while(1)
  {
    int bread = 0;
    int btimeLeft = 0;

    {
      int result = pthread_mutex_lock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_lock() failed");
      }
    }

    bread = (1 == read);

    {
      int result = pthread_mutex_unlock(mutex_read);
      if (0 != result)
      {
        perror("pthread_mutex_unlock() failed");
      }
    }

    {
      int result = pthread_mutex_lock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_lock() failed");
      }
    }

    btimeLeft = (1 == timeLEft);

    {
      int result = pthread_mutex_unlock(mutex_time);
      if (0 != result)
      {
        perror("pthread_mutex_unlock() failed");
      }
    }

    if (bread == 1)
    {

      pthread_cancel(thread2);
      pthread_cancel(thread1);
      break;
    }
    else if (btimeLeft == 1)
    {

      pthread_cancel(thread1);
      pthread_cancel(thread2);
      break;
    }
  }  
  ...

For PThreads thr threas function needs to be declared as:

void * (*) (void *)

This isn't the case for displayTimeLeft


When scanning in a "string" one need to pass the address of the first element of the character array representing the string. So this

scanf("%s", &answer);

should be this

scanf("%s", &answer[0]);

or this

scanf("%s", answer);

The code misses the protoype for sleep(), so add

#include <unistd.h>

Having done so the compiler detects a name clash between the system call read() and the global variable read declared by your code. This is not nice. Rename readto something like readit.


Last not least there is the issue mentioend by suspectus in his answer. You are misusing a pointer to an int to store some time value (int * time = 180). Do not do that.

To fix this do like so:

int main(void)
{
  ...
  int time = 180;
  ...
  ret2 = pthread_create(&thread2, NULL, displayTimeLeft, &time);

and in displayTimeLeft do:

 int time = *((int*) arg);

相关问答

更多

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)