Java HashSet在添加到对象后更改其值

Java HashSet在添加到对象后更改其值,java,hashset,Java,Hashset,我试图向ArrayList对象添加构造函数有3个参数(int、int、hashset)的对象。当我添加一个新对象时,哈希集中的值会发生某种变化,因此我添加了错误的值。例如,我创建了3个对象,添加这3组整数: 142082 74016 122517 57432 97112 142082 150224 112373 129671 57432 97112 138427 115659 102283 147774 142082 31491 129671 855 57432 73545 123160

我试图向ArrayList对象添加构造函数有3个参数(int、int、hashset)的对象。当我添加一个新对象时,哈希集中的值会发生某种变化,因此我添加了错误的值。例如,我创建了3个对象,添加这3组整数:

142082 74016 122517 57432 97112  
142082 150224 112373 129671 57432 97112 138427 115659 102283 147774  
142082 31491 129671 855 57432 73545 123160 124682 147774 61966 58590 
但是object接受了这些:

70213 131022 118104 137949 4003 13798 23598 129525  
70213 131022 118104 137949 4003 13798 23598 129525  
70213 131022 118104 137949 4003 13798 23598 129525 
我不明白为什么集合会改变它的值。这是功能代码:

//Array of ParagData objects
public static ArrayList<ParagData> getAllParagsDatas(String indexed_data_tab) throws SQLException{
    ArrayList<IndexedItem> allIndexedItems = new ArrayList<>();
    ArrayList<ParagData> allParags = new ArrayList<>();
    HashSet<Integer> wordsId = new HashSet<>();
    //Array of all indexed words
    allIndexedItems = GuiFindFrags.myConnection.getAllIndexedItems(indexed_data_tab);

    int curCycledParag = 1; //current paragraph num
    int curCycledTextId = 1; //current text id

    for(int i = 0; i < allIndexedItems.size(); i++){
        if((allIndexedItems.get(i).textId == curCycledTextId) && allIndexedItems.get(i).paragNum == curCycledParag){
            if(allIndexedItems.get(i).wordId != 0) wordsId.add(allIndexedItems.get(i).wordId);
        }
        else {          
            allParags.add(new ParagData(allIndexedItems.get(i).textId, allIndexedItems.get(i).paragNum, wordsId));
            wordsId.clear();
            curCycledParag = allIndexedItems.get(i).paragNum;
            curCycledTextId = allIndexedItems.get(i).textId;
        }
    } 
    return allParags;
}
  • 获取对象的ArrayList Allindexedems,描述文本中的单词(文本在mysql表中)。此对象具有以下参数:

    • int text_id(在其中找到单词的文本)
    • int parag_num(在文本的哪个段落中找到)
    • int word id-(字典中单词的id,也在mysql表中)
    此对象的构造函数中还有其他参数,但此处不使用它们。 所以这个数组列表描述了所有文本中的所有单词

  • 为当前文本和当前段落创建变量。它们将在循环期间发生变化

  • 此外,在开始时,我创建了
    HashSet wordsId
    ——在这个HashSet中,应该添加一段文本的所有单词id。 因此,我开始将
    word\u id
    添加到
    HashSet
    ,同时将每个单词的
    text\u id
    allIndexedItems.get(I).textId
    )=当前文本(变量
    curCycledTextId
    )和单词段落(
    allIndexedItems.get(I).paranum
    )=变量的值
    curCycledParag

    因此:当段落的所有单词都添加到哈希集中时,我必须创建另一个对象,描述段落对象数据(它有:

    • int text_id(本段落所在文本的id)
    • int parag_num(文本中的段落数)
    • HashSet wordIdsSet-(段落的所有单词ID)
    在开始时,我创建了一个
    arraylistallparags
    ,用于添加所有段落对象。函数返回这个ArrayList。 因此,当所有段落单词都添加到HashSet时,我创建了一个新对象ParagData并将其添加到ArrayList allParags。之后,我清理HashSet并使用它添加下一段落的单词ID

    else {              
        allParags.add(new ParagData(allIndexedItems.get(i).textId, allIndexedItems.get(i).paragNum, wordsId));
        wordsId.clear();
        curCycledParag = allIndexedItems.get(i).paragNum;
        curCycledTextId = allIndexedItems.get(i).textId;
    }
    return allParags;
    

  • 当我将新的ParagData对象添加到ArrayList时,它的值会发生变化-因此不正确的值会添加到allParags ArrayList中

    为每个ParagData创建一个新的Hashset对象。Hashset在创建后不是不可变的。您处理的区域是同一个对象。

    能否提供有关您在代码中所做工作的更多信息并对y进行优化我们对可读性很强的表单的输入,要从中提取一些东西并不那么容易。您正在为每个
    ParagData
    实例添加对相同
    HashSet
    对象的引用。为每个实例创建一个
    新HashSet
    。khelwood,在每次在HashSet中添加数据之前,我都会清除它。然后我再次使用它-wordsId.clear();你能不能在没有用户定义对象的情况下给出代码?这样我们就可以很容易地理解了。@nrvmodi,我添加了代码的描述。对不起,我不知道如何使代码更易于阅读。非常感谢!现在它工作得很好。但对我来说还是很奇怪-为什么我不能在想再次使用它时仅使用clear就使用相同的哈希集链接…@Alexey Rumin,如果您尝试清除当前wordsId(哈希集),您在Paradat对象中已扭曲的wordsId(哈希集)引用也将被清除。您需要克隆旧的或创建一个新的进行处理。非常感谢您的解释!
    int curCycledParag = 1; //current paragraph num
    int curCycledTextId = 1; //current text id
    
    else {              
        allParags.add(new ParagData(allIndexedItems.get(i).textId, allIndexedItems.get(i).paragNum, wordsId));
        wordsId.clear();
        curCycledParag = allIndexedItems.get(i).paragNum;
        curCycledTextId = allIndexedItems.get(i).textId;
    }
    return allParags;