将LinkedList <short []>传递给构造函数,它会起作用吗?

Ami*_*mit 1 java collections

我有类SpeexRunner如下,构造函数接受两个参数一个布尔变量和一个LinkedList<short[]>.如下 :-

public class SpeexRunner implements Runnable {
    public boolean stopThread;
    LinkedList<short[]> dataList;

    public SpeexRunner(boolean val_stopThread, LinkedList<short[]> dataRef){
        this.stopThread = val_stopThread;
        dataList = dataRef;
    }
    @Override
    public void run() {
     //add objects in dataList;
     // change / remove dataList Objects
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是: - 如果我在run()中更改dataList,更改是否会反映到原来的列表中,而这个列表是在其他地方声明的?

T.J*_*der 5

如果我在run()中更改dataList,更改是否会反映到其他地方声明的原始列表?

是.构造函数接收对列表的引用,而不是它的副本.如果要复制它,则必须使用LinkedList 复制构造函数.然后你将拥有自己的列表副本.但需要注意的是,项目的两个列表仍然共享,因为条目阵列(short[]),和数组通过引用存储.

这可能是最好的示例:

import java.util.*;

public class ListExample {
    public static final void main(String[] args) {
        List<short[]> list;

        // Direct use (no copies)
        list = new LinkedList<short[]>();
        list.add(new short[] { 0, 0, 0 });
        System.out.println("list.size() before direct use: " + list.size());
        System.out.println("list.get(0)[0] before direct use: " + list.get(0)[0]);
        new DirectUser(list).doSomething();
        System.out.println("list.size() after direct use: " + list.size());
        System.out.println("list.get(0)[0] after direct use: " + list.get(0)[0]);
        // Output, note how both the list and its contents have been changed:
        // list.size() before direct use: 1
        // list.get(0)[0] before direct use: 0
        // list.size() after direct use: 2
        // list.get(0)[0] after direct use: 1

        // Copying the list, but note that the entries are shared by both lists:
        list = new LinkedList<short[]>();
        list.add(new short[] { 0, 0, 0 });
        System.out.println("list.size() before copy-list use: " + list.size());
        System.out.println("list.get(0)[0] before copy-list use: " + list.get(0)[0]);
        new CopyListUser(list).doSomething();
        System.out.println("list.size() after copy-list use: " + list.size());
        System.out.println("list.get(0)[0] after copy-list use: " + list.get(0)[0]);
        // Output, note how our list didn't change (it doesn't have a new entry), but
        // the entry at index 0 *was* changed:
        // list.size() before copy-list use: 1
        // list.get(0)[0] before copy-list use: 0
        // list.size() after copy-list use: 1
        // list.get(0)[0] after copy-list use: 1

        // "Deep" copying, both the list and its entries:
        list = new LinkedList<short[]>();
        list.add(new short[] { 0, 0, 0 });
        System.out.println("list.size() before deep-copy use: " + list.size());
        System.out.println("list.get(0)[0] before deep-copy use: " + list.get(0)[0]);
        new DeepCopyUser(list).doSomething();
        System.out.println("list.size() after deep-copy use: " + list.size());
        System.out.println("list.get(0)[0] after deep-copy use: " + list.get(0)[0]);
        // Output, note that neither the list nor its entries was affected by the call:
        // list.size() before deep-copy use: 1
        // list.get(0)[0] before deep-copy use: 0
        // list.size() after deep-copy use: 1
        // list.get(0)[0] after deep-copy use: 0


        System.exit(0);
    }

    static class DirectUser {
        List<short[]> items;

        DirectUser(List<short[]> items) {
            // DirectUser doesn't copy the list
            this.items = items;
        }

        void doSomething() {
            this.items.get(0)[0] = 1;
            this.items.add(new short[] { 2, 2, 2 });
        }
    }

    static class CopyListUser {
        List<short[]> items;

        CopyListUser(List<short[]> items) {
            // CopyListUser copies the list, but both lists still share items
            this.items = new LinkedList<short[]>(items);
        }

        void doSomething() {
            this.items.get(0)[0] = 1;
            this.items.add(new short[] { 2, 2, 2 });
        }
    }

    static class DeepCopyUser {
        List<short[]> items;

        DeepCopyUser(List<short[]> items) {
            // DeepCopyUser copies the list AND each entry
            this.items = new LinkedList<short[]>();
            for (short[] entry : items) {
                this.items.add(Arrays.copyOf(entry, entry.length));
            }
        }

        void doSomething() {
            this.items.get(0)[0] = 1;
            this.items.add(new short[] { 2, 2, 2 });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

DirectUser使用列表时,在我们的调用代码中,我们看到了对列表的更改(因为它变得更长)及其内容(第一个条目的第一个插槽从更改01).

CopyListUser使用它时,它制作了一个列表的副本,所以我们没有看到我们的调用代码中的列表有任何变化(它没有变得更长).但我们确实看到了对第一个条目的更改(因为两个列表共享相同的数组对象) - 第一个插槽再次更改01.

DeepCopyUser使用它,它使一个副本列表每个条目的副本,这样的事情是完全彻底的分离.我们的调用代码未对列表或其项目进行任何更改.