java ArrayList循环增加add(对象)总是被最后一个覆盖,把new 对象放在循环里面也是,求大神帮忙

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java ArrayList循环增加add(对象)总是被最后一个覆盖,把new 对象放在循环里面也是,求大神帮忙相关的知识,希望对你有一定的参考价值。

BufferedReader reader;
reader=SystemUtil.read();//这是自定义的读取文件的
String line;
SimpleDateFormat sdf=SystemUtil.timeFormat();
List<Employee> list=new ArrayList<Employee>();
try
while((line=reader.readLine())!=null)
Employee emp=new Employee();
String[] part=line.split("\\:");
emp.setPayrollNum(part[0]);
emp.setPhoneNum(part[1]);
emp.setLastName(part[2]);
emp.setFirstName(part[3]);
emp.setInitial(part[4]);
emp.setDepartNum(Integer.parseInt(part[5]));
emp.setJobTitle(part[6]);
try
emp.setHireDate(sdf.parse(part[7]));
catch (ParseException e)
// TODO Auto-generated catch block
e.printStackTrace();

list.add(emp);



catch (IOException e)
return list;

参考技术A

楼主对比下,没发现你的哪里有问题,我是按照你的写的,

参考技术B 你的类成员有静态的,所以最后一次修改时等于把所有类成员变量改了 参考技术C 没有被覆盖,你打断点试试追问

你是说BUG运行么,试过了part的值总是为String[8],这是为什么啊

参考技术D 你确定会被覆盖?好好检查一下是不是别的问题追问

好像不是被覆盖,每次都可以生成不同的对象,但是ArrayList list每次都访问最后一个对象

追答

你在 list.add(emp); 和 return list; 这地方都输出看看里面的值

第5个回答  2013-08-12 代码写的没问题
读取的文件应该有问题追问

文件应该没问题啊

追答

代码是没问题的
我仔细看了下

追问

可是就是不行啊,急死我了,哎

这是现实所有信息类

然后最后打印出来是

619:02-95436669:Wang:Mengjie:X:26:Consultant:12-02-2001

619:02-95436669:Wang:Mengjie:X:26:Consultant:12-02-2001

省略几行,是一样的

大神,大神,求解啊

追答

然后是少了一行么?
arraylist是从0开始的 你是不是少算了一行啊

纯并行添加的Java ArrayList.add() 方法线程安全吗? [复制]

【中文标题】纯并行添加的Java ArrayList.add() 方法线程安全吗? [复制]【英文标题】:Java ArrayList.add() method thread safe for purely parallel adding? [duplicate] 【发布时间】:2015-02-11 02:10:58 【问题描述】:

考虑一个函数的 for 循环,该函数接受一个 ArrayList 引用并将一个对象添加到该 ArrayList。我现在想并行执行每个函数调用。

如果我不关心添加对象的顺序并且没有函数读取或操作任何 ArrayList 元素,那么 ArrayList.add() 方法是否线程安全? 所以我只想确保在并行调用结束时所有对象都被添加到列表中。

【问题讨论】:

可能重复***.com/questions/2715983/… 试试Collections.synchronizedList(new ArrayList&lt;Object&gt;()) 那你不是在找包吗?它可以包含多个,但顺序无关紧要。我不认为 Java 提供了标准实现,但它可能会在以后的搜索中帮助您。 OP 实际需要的是每个线程单独累积其贡献,然后合并来自所有线程的结果。也就是说,他需要Stream.parallel() 就在the documentation 中:"注意这个实现是不同步的。 如果多个线程同时访问ArrayList 实例,并且至少有一个线程修改从结构上看,列表必须在外部同步。” 不是我的重点,粗体和斜体实际上在文档中。文档是您获取信息的第一站。 【参考方案1】:

不,它不是线程安全的。使用Collections.synchronizedList() 包装您的列表,或在访问列表时使用显式同步。

【讨论】:

我想避免同步的开销,因为我不是从 ArrayList 读取...如果两个线程想要同时添加到 ArrayList 会发生什么? 任何事情都可能发生:它可能运行良好,或者元素可能丢失,或者您可能会遇到异常,或者列表可能处于不连贯的状态。让你的程序正确,然后看看它是否足够快。如果不是,并且如果您证明对列表的同步访问是问题(这不太可能),那么请考虑如何优化代码。 如果 OP 得出结论,他会发现没有共享状态模型可以提高他的性能。 如果有人来寻找 addAll(),请注意,不,它也不是线程安全的。【参考方案2】:

为此,您可以使用CopyOnWriteArrayList,因为ArrayList 不是线程安全的。

CopyOnWriteArrayList

编辑: 我只是引用 Oracle 来告诉你,这就是你所需要的:

ArrayList 的线程安全变体,其中所有可变操作(添加、设置等)都是通过制作底层数组的新副本来实现的。 这通常成本太高,但是当遍历操作的数量大大超过突变时,它可能比替代方法更有效,并且在您不能或不想同步遍历但需要排除并发线程之间的干扰时很有用。

【讨论】:

“遍历操作的数量远远超过突变”——这听起来根本不像是对 OP 情况的描述。【参考方案3】:

不,add 方法使用了许多没有线程安全控制的类级别属性。在多个线程中同时调用 add() 很可能会导致问题。

【讨论】:

【参考方案4】:

ArrayList.add() 不是线程安全的。即使您没有从其他线程读取列表,也不应该依赖这个逻辑假设。这是ArrayList.add()的定义:

public boolean add(E e) 
    ensureCapacity(size + 1);
    elementData[size++] = e;
    return true;

作为一个在没有同步的情况下可能出现的问题的示例,size 属性在添加所有元素后可能会不一致。如果稍后尝试获取元素的数量,结果可能不正确。

【讨论】:

这实际上低估了没有同步的问题的全部潜力。即使代码看起来是原子的,它仍然会在没有同步的情况下被破坏。 @MarkoTopolnik 这只是一个简单的例子。【参考方案5】:

不,它不是线程安全的。您有两个选择:

    使用不同的集合:CopyOnWriteArrayList 在多线程环境中修改数组列表时使用显式同步。

【讨论】:

【参考方案6】:

它不是线程安全的。在没有同步的情况下,线程可以践踏彼此对列表的修改,甚至可能看不到彼此对列表的更改。无论哪种方式,它都会被破坏。

您应该首先使用 Collections.synchronizedList 或 synchronized statement 围绕 add 调用使​​代码工作。

如果你发现每个操作的同步开销太大,下一个选择是给每个线程自己的私有 ArrayList,然后定期,或者在最后,将私有 ArrayLists 的内容转储到主 ArrayList .

【讨论】:

以上是关于java ArrayList循环增加add(对象)总是被最后一个覆盖,把new 对象放在循环里面也是,求大神帮忙的主要内容,如果未能解决你的问题,请参考以下文章

纯并行添加的Java ArrayList.add() 方法线程安全吗? [复制]

Java,通过arraylist调用对象方法

关于Java ArrayList 扩容 (JDK 1.8)

Arraylist的遍历方式java反射机制

关于java中ArrayList的快速失败机制的漏洞——使用迭代器循环时删除倒数第二个元素不会报错

Java 中foreach()循环