【问题标题】:Understanding Java's Collections & Mutables - Sizes, Load factors and Thresholds了解 Java 的集合和可变对象 - 大小、负载因子和阈值
【发布时间】:2018-12-22 18:28:03
【问题描述】:

我想了解 Java 集合和可变元素增长的默认大小和阈值。

我创建了一个简单的程序来声明它们,并在最后一个 SysOut 语句中添加了一个调试器,然后检查了引用。

我已经评论了调查结果,但想详细了解 LoadFactor 和 Thresholds,如果有人可以提供简单易懂的解释。

以下是我用来获取结果的程序 -

public class CollectionInfo {

    public static void main(String[] args) {
        Map<Integer,String> hashMap = new HashMap<>();
        Map<Integer,String> linkedHashMap = new LinkedHashMap<>();
        Map<Integer,String> treeMap = new TreeMap<>();

        Set<String> hashSet = new HashSet();
        Set<String> linkedhashSet = new LinkedHashSet();
        Set<String> treeSet = new TreeSet();

        List<String> arrayList = new ArrayList();
        List<String> linkedList = new LinkedList();
        List<String> vector = new Vector<>();

        StringBuilder builder = new StringBuilder();
        StringBuffer buffer = new StringBuffer();

        //Table - 16, LoadFactor - 12, Threshhold - 0.75
        hashMap.put(1, "a");

        //Table - 16, LoadFactor - 12, Threshhold - 0.75
        linkedHashMap.put(1, "a");

        treeMap.put(1, "a");

        //Table - 16, LoadFactor - 12, Threshhold - 0.75
        hashSet.add("a");

        //Table - 16, LoadFactor - 12, Threshhold - 0.75
        linkedhashSet.add("a");

        treeSet.add("a");

        //ElementData - 10
        arrayList.add("a");

        //Has First and Last
        linkedList.add("a");

        vector.add("a");

        //Size - 16
        builder.append("a");

        //Size - 16
        buffer.append("a");

        System.out.println("Added debugger to this line and please inspect the references");

    }
}

【问题讨论】:

    标签: java string collections


    【解决方案1】:

    简单来说,

    HashMap 和 Hashset 在插入新节点时会调整其内部结构,TreeMap 通常不会在添加新节点时调整其节点。 ArrayList 和 LinkedList 的方式相同:第一个调整为 resize,而第二个不调整。这就是为什么设置 TreeMap 的初始大小与尝试设置 LinkedList 的初始大小大致相同的原因。

    如果您看到 hashmap 和 arraylist 具有随机访问权限,那么定义初始容量和负载因子也是有意义的,但是 treemap/linkedlist 必须进行顺序搜索才能访问任何值,因此即使您提供初始容量也没有任何意义这些集合的工作方式。

    stringbuilder 和 stringbuffer 是可变类型的字符串操作,因此您需要随机访问字符串的任何字符,因此很明显这两个应该由数组/数组列表类型的数据结构支持,正如我上面所说我们需要为存储字符串字符的缓冲区提供初始容量,javadocs 说

    "只要字符串缓冲区包含的字符序列长度不超过容量,就不需要分配新的内部缓冲区数组,如果内部缓冲区溢出,会自动变大。"

    【讨论】:

    • 这是否意味着具有默认大小(例如 16 或 10)的集合和可变对象在每个元素添加到它们后会增长?负载因子和阈值是如何出现的?
    • 对于arraylist,大小取决于内部支持的array,一旦满了,大小增加2倍,当前arraylist的所有元素都将被复制到新的arraylist。(因此负载因子概念不适用于数组列表)
    • 对于 Maps,java 将在每次插入后检查,如果当前容量
    • 请查看 java 文档以进一步了解初始容量和负载系数docs.oracle.com/javase/6/docs/api/java/util/HashMap.html
    猜你喜欢
    • 2018-11-03
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    相关资源
    最近更新 更多