【问题标题】:Why do my ArrayList of Arraylist values change back after I set them? [closed]为什么我的 ArrayList 的 ArrayList 值在设置后会变回来? [关闭]
【发布时间】:2025-12-30 19:45:06
【问题描述】:

不幸的是,我正在使用 ArrayLists of ArrayLists of ArrayLists 的 ArrayLists。我对 Java 很陌生,所以这对我来说可能是一个简单的错误(我已经习惯了 Perl)。我正在对一些代码进行故障排除,其中我构建了空 ArrayList^4 的完整结构(它代表固定数量的数据字段,这些字段永远不会更改,但具有已修改的值),然后尝试摄取文件,设置使用 ArrayList.get() 和 ArrayList.set() 的嵌套值。下面是代码——从文件中读入行(进入 ArrayList 行)并迭代以分段添加到 ArrayList^4(称为 DB)。

读入“行”ArrayList 的输入数据的一般格式大致如下-- 抱歉让眼睛难看了。每个 0 可以是任意字符串:

ID  0.0-0.0 0.0-0.0 0.0-0.0 0.0-0.0 0.0-0.0

DB 是最终的 ArrayList^4,四个嵌套的数组列表都包含一定数量的占位符字符串。它是通过将零的 ArrayLists 顺序添加到 ArrayList^2 来构建的,然后将它们添加到 Arraylist^3,这是添加到 DB 的 Line。输入数据被各种分隔符分解,用来替换这些占位符字符串。

ArrayList<String> Single = new ArrayList<String>();
    for(int i = 0; i < 2; i++) {
        Single.add("0"); }

ArrayList<ArrayList<String>> Squared = new ArrayList<ArrayList<String>>();
    Squared.add(Single);
    Squared.add(Single);

ArrayList<ArrayList<ArrayList<String>>> Line = new ArrayList<ArrayList<ArrayList<String>>>();
    Line.add(Squared);
    //repeat to make 5 items in list

数据的分隔符在技术上是 \n、\t、- 和 .按这个顺序。

我在一行中使用 j+1 因为输入文件的第一列(总共六列)只是一个标题(因此被添加到 ArrayList“信息”中),所以它在其余部分被跳过数据处理。

for (int i = 0; i < linesSize; i ++) {
    DB.add(Line); //Line is an ArrayList^3 containing the "empty" values for the given line
    List<String> columns = Arrays.asList(lines.get(i).split("\t"));
    info.add(columns.get(0));
    for (int j = 0; j < 5; j ++) {
        List<String> categories = Arrays.asList(columns.get(j+1).split("-"));
        int categoriesSize = categories.size();
        for (int k = 0; k < categoriesSize; k ++) {
            List<String> elements = Arrays.asList(categories.get(k).split(Pattern.quote(".")));
            int elementsSize = elements.size();
            for (int l = 0; l < elementsSize; l ++) {
                String id = elements.get(l);
                //System.out.println("before:" + DB.get(i).get(j).get(k).get(l));
                DB.get(i).get(j).get(k).set(l, id);
                //System.out.println("after:" + DB.get(i).get(j).get(k).get(l) + "\n");
            }
        }
    }
}

我已经包含了故障排除注释行,因为它们告诉我值正在被改回。例如,我会看到

Before: 0
After: X

但接下来几行:

Before: X
After: 0

除非在我的循环中发生意外的事情,否则数据没有理由变回......我已经盯着它看了一段时间无济于事。我检查了所有的 Size 变量,它们似乎正确地出来了。当我重新组装数据时,输出文件也会正确打印(代码未显示)。我还在单独的先前循环中使用了 DB.add(Line),以防它搞砸了,但没有骰子。

如果我遗漏了什么,请告诉我!谢谢!我也知道可能有更好的方法可以做到这一点,但这必须奏效;它不必特别高效或优雅。

【问题讨论】:

  • 这不是一个最小的可复制示例。什么是数据库?
  • 当你第一次使用Columnsj时你使用j+1。但后来你在执行get 时只使用j。对我来说,您可以使用 jj+1 用于从 0 to 4 开始的同一个循环,这没有任何意义。我认为您要么会错过某些东西,要么会抛出异常。但是没有一些样本数据很难确定。
  • 抱歉,这让我很困惑。输入数据文件和DB结构除了ID列是一样的,所以j+1和j的切换就是把它们排成一行。列索引 0 指向输入文件中的名称,但数据库中的实际数据。

标签: java arraylist java-8 iteration


【解决方案1】:

更伤眼的是对变量使用大写字母:根据所有 Java 样式指南,“Single”、“Square”、“Line”应该是小写。但这不是您的问题的原因。

您正在向 DB 对象多次添加相同的“行”。您应该为每一行创建一个新的 ArrayList(),否则如果您将一个项目添加到 Line 列表,它会为每个索引“i”添加。

'single' 和 'squared' 同样适用,您将相同的 'single' Arraylist 添加到 'squared' 中多次,而不是每次都添加一个新的,因此它们也不会不同。

【讨论】:

  • 哦,有道理。所以我一直在添加的每个“Line”实例都与其他实例共享其所有值,这就是为什么它都被重置了?
  • 不,不共享,是同一个实例(同一个内存位置)
最近更新 更多