使用最终静态列表中的默认值填充列表

时间:2012-10-14 16:44:02

标签: java list map

标题可能不是最好的,我为此道歉。

我有几个最终的静态列表,用于定义数据库值的默认值。默认值列表永远不会更改,因此在填充它们时,我使用Collections.nCopies(int,T)来获取不可变列表。然后,这些列表用于使用默认值填充另一个类中的列表。这些列表中的值预计会发生变化。

默认类的伪代码:

public final class FooDefaults {
    public final static List<Integer> LIST_ONE;
    public final static List<String> LIST_TWO;
    //This map allows easier access to "column" values.
    public final static List<Map<String,String>> LIST_THREE;

    static {
        LIST_ONE = Collections.nCopies(7, 5);
        LIST_TWO = Collections.nCopies(10, "boo");
        Map<String, String> temp = new java.util.LinkedHashMap<>();
        for(int i=0;i<15;i++) {
            temp.put(("Param"+i),"foo");
        }
        LIST_THREE = Collections.nCopies(10, temp);
    }
}

可编辑值类的伪代码:

public class Foo {
    //Keep the reference from changing.
    //Prevents an accidental new.
    private final List<Integer> listOne;
    private final List<String> listTwo;
    private final List<Map<String,String>> listThree;

    public Foo() {
        listOne = new java.util.ArrayList<>(FooDefaults.listOne);
        listTwo = new java.util.ArrayList<>(FooDefaults.listTwo);
        listThree = new java.util.ArrayList<>(FooDefaults.listThree);
    }
}

我担心的是,由于我在这些列表上执行了浅拷贝,因此Foo中列表的更改将显示在FooDefaults的列表中。

这篇文章:https://stackoverflow.com/a/1685158/1391956表明由于字符串和整数是不可变的,我不必担心意外覆盖FooDefaults.LIST_ONE和FooDefaults.LIST_TWO中的值。

因此,我主要关心的是FooDefaults.LIST_THREE中地图中包含的值。如果我在Foo的listThree中更改地图中的值,那么更改是否会在FooDefaults中显示?

如果是这样,最有效的方法是什么?类Foo可能会被实例化一千多次并被添加到另一个类的List中,因此速度可能是一个问题。

我最初是为了速度而在FooDefaults中创建了最终的静态列表,因为我的(可能是不正确的)假设在FooDefaults中创建这些列表并且只是复制数据比在每次实例化Foo时创建它们更快。

编辑:如果我必须执行深层复制,我计划使用类似的东西:

public static final List<Map<String, String>> getListThreeCopy() {
    Map<String,String> temp = new java.util.LinkedHashMap<>();
    for(Map.Entry<String, String> entry: LIST_THREE.get(0).entrySet()) {
        temp.put(entry.getKey(),entry.getValue());
    }

    List<Map<String,String>> rtnList = new java.util.ArrayList<>();
    for(int i=0;i<LIST_THREE.size();i++) {
        rtnList.add(temp);
    }
    return rtnList;
}

会有更快的方式吗?

1 个答案:

答案 0 :(得分:0)

最后,我在循环中使用了帖子末尾提到的代码来执行1,500次Deep Copy并计时。我对实例化代码做了同样的事情。

正如我所料,从头开始重新创建List要比深层复制快得多。

深度复制为16毫秒,实例化为0毫秒。我使用System.currentTimeMillis()定时它。

只要我只在静态函数中创建它,我就没有理由担心错误。