• Java中的集合类


         数组是一种很常见的数据结构,开始接触编程的时候多数程序都和数组相关。刚开始接触Java时也是一直使用数组写一些程序,后来越来越觉得数组这东西没法满足需求了,这时一位“前辈”对我说了一句:不会用集合类就等于没学过Java。然后才知道有集合类。
    什么时候数组会显得力不从心,没法满足需求,需要集合类呢?

    不知道具体数据长度
    需要自动排序
    存储键值对

         当然,上面的情况不是绝对的,只是数组比较难满足。这时集合类(也可称为容器类)就显示了它强大的功能。

         集合类的分类

    上图中不包含Queue内容,部分Map的实现类未给出。常见使用的有List、Set、Map及他们的实现类。

    List、Set、Map接口及各实现类的特性

    接口

    特性

    实现类

    实现类特性

    成员要求

    List

    线性、有序的存储容器,可通过索引访问元素

    ArrayList

    数组实现。非同步。

    Vector

    类似ArrayList,同步。

    LinkedList

    双向链表。非同步。

    Map

    保存键值对成员

    HashMap

    基于哈希表的 Map 接口的实现,满足通用需求

    任意Object对象,如果修改了equals方法,需同时修改hashCode方法

    TreeMap

    默认根据自然顺序进行排序,或者根据创建映射时提供的 Comparator进行排序

    键成员要求实现caparable接口,或者使用Comparator构造TreeMap。键成员一般为同一类型。

    LinkedHashMap

    类似于HashMap,但迭代遍历时取得“键值对”的顺序是其插入顺序或者最近最少使用的次序

    与HashMap相同

    IdentityHashMap

    使用==取代equals()对“键值”进行比较的散列映射

    成员通过==判断是否相等

    WeakHashMap

    弱键映射,允许释放映射所指向的对象

    ConcurrentHashMap

    线性安全的Map

    Set

    成员不能重复

    HashSet

    为快速查找设计的Set

    元素必须定义hashCode()

    TreeSet

    保持次序的Set,底层为树结构

    元素必须实现Comparable接口

    LinkedHashSet

    内部使用链表维护元素的顺序(插入的次序)

    元素必须定义hashCode()

    List基本操作
    ArrayList<String> arrayList = new ArrayList<String>();
            arrayList.add("Tom");
            arrayList.add("Jerry");
            arrayList.add("Micky");
            // 使用Iterator遍历元素
            Iterator<String> it = arrayList.iterator();
            while (it.hasNext()) {
                String str = it.next();
                System.out.println(str);
            }
            // 在指定位置插入元素
            arrayList.add(2, "Kate");
            // 通过索引直接访问元素
            for (int i = 0; i < arrayList.size(); i++) {
                System.out.println(arrayList.get(i));
            }
            List<String> subList = new ArrayList<String>();
            subList.add("Mike");
            // addAll(Collection<? extends String> c)添加所给集合中的所有元素
            arrayList.addAll(subList);
            // 判断是否包含某个元素
            if (arrayList.contains("Mike")) {
                System.out.println("Mike is include in the list");
            }
    
            LinkedList<String> linkedList = new LinkedList<String>();
            linkedList.addAll(arrayList);
            // 获取指定元素
            System.out.println(linkedList.get(4));
            // 获取第一个元素
            System.out.println(linkedList.getFirst());
            // 获取最后一个元素
            System.out.println(linkedList.getLast());
            // 获取并删除第一个元素
            System.out.println(linkedList.pollFirst());
            // 获取,但不移除第一个元素
            System.out.println(linkedList.peekFirst());
    

    ArrayList和LinkedList的效率比较  

    ArrayList添加元素的效率
    ArrayList<String> arrList = new ArrayList<String>();
            long startTimeMillis, endTimeMillis;
            startTimeMillis = System.currentTimeMillis();
            for (int i = 0; i < 10000; i++) {
                arrList.add(0, "addString");
            }
            endTimeMillis = System.currentTimeMillis();
            System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
                    + "ms");
    
            arrList.clear();
    
            startTimeMillis = System.currentTimeMillis();
            for (int i = 0; i < 20000; i++) {
                arrList.add(0, "addString");
            }
            endTimeMillis = System.currentTimeMillis();
            System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
                    + "ms");
    
            arrList.clear();
    
            startTimeMillis = System.currentTimeMillis();
            for (int i = 0; i < 40000; i++) {
                arrList.add(0, "addString");
            }
            endTimeMillis = System.currentTimeMillis();
            System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
                    + "ms");
    
            arrList.clear();
    
            startTimeMillis = System.currentTimeMillis();
            for (int i = 0; i < 80000; i++) {
                arrList.add(0, "addString");
            }
            endTimeMillis = System.currentTimeMillis();
            System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
                    + "ms");
    
            arrList.clear();
    
            startTimeMillis = System.currentTimeMillis();
            for (int i = 0; i < 160000; i++) {
                arrList.add(0, "addString");
            }
            endTimeMillis = System.currentTimeMillis();
            System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
                    + "ms");
    
            arrList.clear();
    
            startTimeMillis = System.currentTimeMillis();
            for (int i = 0; i < 320000; i++) {
                arrList.add(0, "addString");
            }
            endTimeMillis = System.currentTimeMillis();
            System.out.println("ArrayList:" + (endTimeMillis - startTimeMillis)
                    + "ms");
    

      

    执行时间比较

    执行次数(在0号位置插入)

    ArrayList所用时间(ms)

    LinkedList所用时间(ms)

    10000

    31

    0

    20000

    141

    0

    40000

    484

    16

    80000

    1985

    0

    160000

    7906

    0

    320000

    31719

    16

    执行次数(在尾部插入)

    ArrayList所用时间(ms)

    LinkedList所用时间(ms)

    10000

    0

    0

    20000

    15

    0

    40000

    0

    0

    80000

    0

    0

    160000

    0

    15

    320000

    0

    16

    循环输出次数(get(index)方法)

    ArrayList所用时间(ms)

    LinkedList所用时间(ms)

    10000

    93

    204

    20000

    188

    797

    40000

    328

    2734

    80000

    688

    13328

    160000

    1594

    62313

    320000

    2765

    太久了……

          因为ArrayList底层由数组实现,在0号位置插入时将移动list的所有元素,在末尾插入元素时不需要移动。LinkedList是双向链表,在任意位置插入元素所需时间均相同。所以在List中有较多插入和删除操作的情况下应使用LinkedList来提高效率,而有较多索引查询的时候使用ArrayList(使用增强型的for循环或Iterator遍历LinkedList效率将提高很多)。

    Map基本操作
    HashMap<String, Integer> map = new HashMap<String, Integer>();
            // 向Map中添加元素
            map.put("Tom", 26);
            map.put("Jack", 18);
            map.put("Micky", 17);
            map.put("Kate", 15);
            // 根据Key获取Value
            System.out.println("Jack is " + map.get("Jack") + " years old");
            // 移除
            map.remove("Micky");
            // 遍历Map
            for (Entry<String, Integer> entry : map.entrySet()) {
                System.out.println("name:" + entry.getKey() + " age:"
                        + entry.getValue());
            }
            // Key相同的元素将被覆盖
            map.put("Jack", 19);
            // 根据Key获取Value
            System.out.println("Jack is " + map.get("Jack") + " years old");
            // 判断是否包含某个Key
            if (map.containsKey("Tom")) {
                System.out.println(map.get("Tom"));
            }
            // 判断是否包含某个Value
            if (map.containsValue(26)) {
                System.out.println("The map include the value 26");
            }
            // 判断map是否为空
            if (!map.isEmpty()) {
                // 获取map大小
                System.out.println("The map's size=" + map.size());
            }
            // 获取Key的集合
            for (String str : map.keySet()) {
                System.out.println(str);
            }
    
            TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>();
            treeMap.putAll(map);
            // 输出内容按照key值排序
            for (Entry<String, Integer> entry : treeMap.entrySet()) {
                System.out.println("name:" + entry.getKey() + " age:"
                        + entry.getValue());
                // name:Jack age:19
                // name:Kate age:15
                // name:Tom age:26
            }
    
            LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<String, Integer>();
            // 向Map中添加元素
            linkedHashMap.put("Tom", 26);
            linkedHashMap.put("Jack", 18);
            linkedHashMap.put("Micky", 17);
            linkedHashMap.put("Kate", 15);
            // 保持了插入的顺序
            for (Entry<String, Integer> entry : linkedHashMap.entrySet()) {
                System.out.println("name:" + entry.getKey() + " age:"
                        + entry.getValue());
                // name:Tom age:26
                // name:Jack age:18
                // name:Micky age:17
                // name:Kate age:15
            }
    

      

    Set基础操作
               List<Integer> list = new ArrayList<Integer>();
               list.add(3);
               list.add(4);
               HashSet<Integer> hashSet = new HashSet<Integer>();
               hashSet.add(1);
               hashSet.add(3);
               hashSet.add(2);
               hashSet.add(6);
               // 重复元素将不能被添加
               hashSet.add(3);
               // 只要有元素被添加就返回true
               if (hashSet.addAll(list)) {
                   System.out.println("Add success");
               }
               // 判断是否存在某个集合
               if (hashSet.containsAll(list)) {
                   System.out.println("The hashSet is contain 3 and 4");
               }
               Iterator<Integer> it = hashSet.iterator();
               while (it.hasNext()) {
                   System.out.print(it.next() + " ");
                   // 1 2 3 4 6
                   // 看结果是被排序了,HashSet按照Hash函数排序,Integer值的HashCode就是其int值
               }
               // 换转成数组
               Object[] integers = hashSet.toArray();
               for (int i = 0; i < integers.length; i++) {
                   System.out.print((Integer) integers[i]);
               }
               //移除元素
               hashSet.remove(3);
               
               TreeSet<String> treeSet = new TreeSet<String>();
               treeSet.add("C");
               treeSet.add("A");
               treeSet.add("D");
               treeSet.add("B");
               for (Iterator<String> strIt = treeSet.iterator(); strIt.hasNext();) {
                   System.out.print(strIt.next());
                   // ABCD 按照字母顺序
               }
               LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
               linkedHashSet.add("C");
               linkedHashSet.add("A");
               linkedHashSet.add("D");
               linkedHashSet.add("B");
               for (Iterator<String> linkedIt = linkedHashSet.iterator(); linkedIt
                       .hasNext();) {
                   System.out.print(linkedIt.next());
                   // CADB 按照插入顺序
               }
    

      

  • 相关阅读:
    linux环境变量
    oracle 11g RAC日志分布
    解决Centos下载文件出现”wget: unabl(www.111cn.net)e to resolve host address”
    转载:root用户无法删除文件 rm: cannot remove Readonly file system
    占用端口
    数学小记
    很多问题的解决都是从简单的方式入手不断优化的
    机器学习之算法学习
    机器学习之二分类
    机器学习之模型评估(损失函数的选择)
  • 原文地址:https://www.cnblogs.com/danbing/p/5076990.html
Copyright © 2020-2023  润新知