【问题标题】:Recursive function changes original array?递归函数改变原始数组?
【发布时间】:2013-01-16 07:39:22
【问题描述】:

我有一个递归函数需要创建一个由特殊对象组成的数组...

我的自定义对象是从这个类中填充的:

public class CategoryItem {

boolean hasSubCategories = false;
ArrayList<CategoryItem> subs;
ArrayList<Integer> positions;
String categoryName, categoryId;

// They have setter and getter methods

}

这是我的递归函数:

public ArrayList<CategoryItem> GetLists(ArrayList<Integer> positions, int to) {

    ArrayList<CategoryItem> items = new ArrayList<CategoryItem>();
    for(int i = 0; i < to; i++) {
        CategoryItem item = new CategoryItem();
        item.setHasSubCategories(RandomBool());
        item.setCategoryName("Category " + i);
        item.setCategoryId(RandomId());
        ArrayList<Integer> pos = positions;
        pos.add(i);
            Log.d(LOG, "positions: " + positions);
        Log.d(LOG, "pos: " + pos);
        item.setPositions(pos);
        if(item.isHasSubCategories()) {
            item.setSubs(GetLists(item.getPositions(), i));
        }
        items.add(item);
    }
    return items;

}

在这个函数中,RandomBool() 方法随机返回真/假……而 RandomId() 也不重要……

问题出在“位置”数组上。我想让每个项目都有特定的位置数组,例如:

第一步,每个项目都需要: [0]、[1]、[2]、[3] ...

对于下一步,假设我们选择了位置 3: [3,0], [3,1], [3,2]

但我发现,当我将一个项目添加到 pos 数组时,我暂时分配它以不更改递归函数上的原始项目,它也被添加到原来的位置数组中。所以第一步的结果是这样的: [0,1,2,3] 在每个项目上。

日志是这样的:

positions: []
pos: []
positions: [0]
pos: [0]
positions: [0, 1]
pos: [0, 1]
positions: [0, 1, 2]
pos: [0, 1, 2]
positions: [0, 1, 2, 0]
pos: [0, 1, 2, 0]
positions: [0, 1, 2, 0, 1]
pos: [0, 1, 2, 0, 1]

如何防止这种情况并使其发挥作用?哪里有问题? 任何帮助表示赞赏。谢谢...

【问题讨论】:

    标签: java arrays recursion


    【解决方案1】:

    我暂时指定它不要更改递归函数的原始函数

    你有 C/C++ 背景吗?

    A = B
    

    不会在 java 中制作副本。它们都将指向同一个对象。这有点像所有变量都只是 C 指针。

    您应该使用copy constructor 来制作列表的副本。

    ArrayList<Integer> pos = new ArrayList<Integer>(positions);
    

    【讨论】:

    • 我也试过:ArrayList pos = (ArrayList) position.clone();但它也没有帮助......那么怎么做呢?
    • 愚蠢的错误 :) 非常感谢...我会在几分钟内接受您的回答...
    • @yahya 不客气,我花了一段时间才掌握甚至认识到这一事实。如果您来自 C/C++ 方面,请将 java 中的所有变量视为美化的指针。
    【解决方案2】:

    您可以认为ArrayList&lt;Integer&gt; pos = positions; 就像您分配了指向ArrayList 的指针(在C/C++ 世界中),这意味着您将修改函数内部的原始列表。要在本地列表上工作,您必须创建新列表并使用它:

    ArrayLis<Integer> copiedList = new ArrayList<Integer>(ooriginalList);
    

    【讨论】:

    • 一个指针,而不是一个引用,List 也不起作用,因为他的函数需要 ArrayList
    猜你喜欢
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    相关资源
    最近更新 更多