Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ArrayList内容意外修改_Java_Collections_Arraylist - Fatal编程技术网

Java ArrayList内容意外修改

Java ArrayList内容意外修改,java,collections,arraylist,Java,Collections,Arraylist,从一本旧的java认证书中抽出一个面试问题,这本书是我当年的 我真的不想知道这是否是一个好的面试问题。它的目的是作为一个简单的健全性检查,以确保该人员在Java中处理简单集合的工作已经足够了。。。我没想到会有一个不正确的答案,无论如何,他们在一路上的几个步骤中都弄错了。。。因此,它达到了目的 但令我惊讶的是,在将其放入RAD并运行之后,它是第8步的输出。。。java的行为就好像addAll后的list1没有保存list2中包含的值一样,将引用放在list2中?!因为清除列表2改变了列表1的内容

从一本旧的java认证书中抽出一个面试问题,这本书是我当年的

我真的不想知道这是否是一个好的面试问题。它的目的是作为一个简单的健全性检查,以确保该人员在Java中处理简单集合的工作已经足够了。。。我没想到会有一个不正确的答案,无论如何,他们在一路上的几个步骤中都弄错了。。。因此,它达到了目的

但令我惊讶的是,在将其放入RAD并运行之后,它是第8步的输出。。。java的行为就好像addAll后的list1没有保存list2中包含的值一样,将引用放在list2中?!因为清除列表2改变了列表1的内容

然而,在第7步清除之前对列表2的修改对列表1没有影响。。。我的一天的工作现在将脱轨通过文件收集实施lol。。。这根本不是我所期望的。。。有人能解释一下第8步列表1内容的原因吗

public static void main(String[] args)
{
    List list = new ArrayList();
    System.out.println("1: List1 Post - Constructor\t\t" + list);
    System.out.println();

    list.add("1");
    System.out.println("2: List1 Post - Add 1\t\t\t\t" + list);
    System.out.println();

    list.add("2");
    System.out.println("3: List1 Post - Add 2\t\t\t\t" + list);
    System.out.println();

    list.add(1,"3");
    System.out.println("4: List1 Post - Add three at index 1\t\t" + list);
    System.out.println();

    List list2 = new ArrayList(list);
    System.out.println("5: List1 Post - list2 Constructor\t\t" + list);
    System.out.println("5: List2 Post - list2 Constructor\t\t" + list2);
    System.out.println();

    list.addAll(list2);
    System.out.println("6: List1 Post - Add list2 to list1\t\t" + list);
    System.out.println("6: List2 Post - Add list2 to list1\t\t" +list2);
    System.out.println();

    list2 = list.subList(2,5);
    System.out.println("7: List1 Post - List 2 sublist of list 2,5\t" + list);
    System.out.println("7: List2 Post - List 2 sublist of list 2,5\t" + list2);
    System.out.println();

    list2.clear();
    System.out.println("8: List1 Post - list2 clear\t\t\t" + list);
    System.out.println("8: List2 Post - list2 clear\t\t\t" + list2);
    System.out.println();
}

因为清除列表2改变了列表1的内容

对。因为
ArrayList.subList
遵循以下记录的行为:

返回此列表中指定的fromIndex(包含)和toIndex(独占)之间部分的视图。(如果fromIndex和toIndex相等,则返回的列表为空。)返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然。返回的列表支持此列表支持的所有可选列表操作

此方法消除了显式范围操作的需要(通常存在于数组中)。通过传递子列表视图而不是整个列表,任何需要列表的操作都可以用作范围操作。例如,以下习惯用法从列表中删除一系列元素:

 list.subList(from, to).clear();
这特别给出了通过在子列表视图上调用
clear
来删除列表部分的示例。

每当调用该函数时,它都会返回
子列表
类的实例:

public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
    }
这个类有几个实现的函数,包括:
get()、set(int-index,ee)、size()、add(ee)、remove(ee)、removeRange(int-fromfindex,int-toIndex)
等等;调用,最终对父级进行更改。有关与上下文的相关性,请参见
removeRange(int-fromIndex,int-toIndex)
函数的实现:

protected void removeRange(int fromIndex, int toIndex) {
        checkForComodification();
        parent.removeRange(parentOffset + fromIndex,
                           parentOffset + toIndex);   // <--- removing parent
        this.modCount = parent.modCount;
        this.size -= toIndex - fromIndex;
    }
因此,调用
ArrayList.subList(fromIndex,toIndex)
返回的list实例的
clear()
函数对
ArrayList
本身进行更改。通过以下语句支持此实现:

返回此列表中指定区域之间部分的视图 从索引(包含)到索引(独占)。(如果来自索引和 toIndex相等时,返回的列表为空。)返回的列表为 由该列表支持,因此返回列表中的非结构性更改 反映在此列表中,反之亦然。返回的列表支持 所有可选的列表操作


谢谢Jon,我一直在关注addAll或clear方法作为皱纹,没有意识到它是子列表。。。我不知道的怪癖。
private class SubList extends AbstractList<E> implements RandomAccess {
        private final AbstractList<E> parent;
        private final int parentOffset;
        private final int offset;
        int size;

        SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) {
            // constructor assignment variable
        }
        // other implemented function
 }
protected void removeRange(int fromIndex, int toIndex) {
        checkForComodification();
        parent.removeRange(parentOffset + fromIndex,
                           parentOffset + toIndex);   // <--- removing parent
        this.modCount = parent.modCount;
        this.size -= toIndex - fromIndex;
    }
public void clear() {
        removeRange(0, size());
    }