java arraylist.add用最后一个值覆盖

时间:2014-05-08 00:47:51

标签: java arraylist

有这个课程

public class ObjetoOS {

private ArrayList<String> atribute = new ArrayList<String>();

public ObjetoOS (String a){
    atribute.add(a);
}

public ObjetoOS (ArrayList<String> a){
    atribute = a;
    }

我喜欢这个

public class TablaSimbolica {

    private static ArrayList<ObjetoOS> tableOS = null;

    public static void addAtributos(ArrayList<String> newOnes){

    if (tableOS == null){
        tableOS = new ArrayList<ObjetoOS>();
        for (String s : newOnes){
            ObjetoOS newObj = new ObjetoOS(s);
            tableOS.add(newObj);
        }
    }
    else{
        ArrayList<ObjetoOS> aux = new ArrayList<ObjetoOS>();
        for (ObjetoOS os : tableOS){
            ArrayList<String> oldOnes = new ArrayList<String>();
            oldOnes = os.getAtributo();
            for (String s : newOnes){
                oldOnes.add(s);
                ObjetoOS newObj = new ObjetoOS(oldOnes);
                aux.add(newObj);
                newObj = null;
                oldOnes.remove(s);
            }
        }   
        tableOS = aux;
    }

}

所以基本上:addAtributos检查数组是否为空。如果它只是添加字符串,如果不是,我必须将它与新的组合,就像一个购物产品。

在添加新字符串时,虽然我正在创建一个新数组,并且在添加它之后将其转为null的新objectOS,但元素会覆盖最后一个。

例如,如果我有字符串&#34; true&#34; &#34; false&#34;,我必须添加&#34;女性&#34; &#34;男&#34;,输出为:

[TRUE, Female]

[TRUE, Male]
[TRUE, Male]

[TRUE]
[TRUE]
[FALSE, Female]

[TRUE]
[TRUE]
[FALSE, Male]
[FALSE, Male]

我无法弄清楚我在哪里错过了这一点。如果我从ArrayList tablaOS或addAtributos方法中删除静态,它会给我一个错误。

编辑:已解决!我改变了对象类,创建了一个新的空构造函数,并添加了一个带有for。

的字符串数组的方法

它最终成为

的循环
for (String s : newOnes){
    oldOnes.add(s);
    ObjetoOS nuevo = new ObjetoOS();
    nuevo.addAtribute(oldOnes);
    aux.add(nuevo);
    oldOnes.remove(s);

2 个答案:

答案 0 :(得分:1)

你的一些问题在于:

ArrayList<String> oldOnes= new ArrayList<String>(); // This line is pointless
oldOnes= os.getAtributo();                          // oldOnes will be overwritten here
    for (String s : newOnes)
    {
       oldOnes.add(s);
       ObjetoOS newObj = new ObjetoOS(oldOnes);
       aux.add(newObj );
       newObj = null;
       oldOnes.remove(s);
    }

当您将oldOnes传递给ObjetoOS构造函数时,newObj将引用与oldOnes相同的列表,之后您将从中删除元素oldOnes您也会将其从newObj's列表中删除(因为它们是相同的)。

如果使用String构造函数,则不会发生同样的情况,因为原始数据类型(也包括Strings)在传递给方法时会被复制(按值传递)。

这里有关于如何在java中传递对象的一个​​很好的解释:Is Java "pass-by-reference" or "pass-by-value"?

修改 此外,每次调用方法时,tableOS都会指向新的ArrayList<>,如果我正确理解您的解决方案,则可能更符合您的要求:

...
    for (ObjetoOS os : tableOS)
    {
        for (String s : newOnes)
        {
            ArrayList<String> oldOnesPlusNewOne = new ArrayList<>();
            oldOnesPlusNewOne.addAll(os.getAtributo());
            oldOnesPlusNewOne.add(s);
            ObjetoOS newObj = new ObjetoOS(oldOnesPlusNewOne);
            tableOS.add(newObj);
        }
    } 

答案 1 :(得分:1)

我可以建议简化一些代码吗?如果您尝试将属性添加到数组列表,则可以创建属性类。你可以为atributos创建一个类,给它一些成员等等......然后轻松改变并使atributos成为一个列表来保存aritbutos。我建议这个班级名为Atributo。你试图在一堂课中做很多事情。单一责任是关键。一个定义atributo的类,一个用于存储它们列表的类。这应该可以解决您的问题并使您的代码简单化。现在,您只能将10个成员存储到数组列表中,而无需指定要保留的元素数量。如果你不这样做,它将只保留默认值10,最后一个元素将被覆盖。

import java.util.ArrayList;

public class Atributos 
{
    // attributes list
    ArrayList<String> atributos = new ArrayList<String>();

    // add string to attributes list
    public void addAtributos(String atributo)
    {
        atributos.add(atributo);
    }

    // add list of strings to attribute list
    public void addAtributos(ArrayList<String> atributo)
    {
        for(String attr : atributo)
        {
            atributos.add(attr);
        }
    }
}