zoukankan      html  css  js  c++  java
  • 总结:Java 集合进阶精讲1

    知识点:Java 集合框架图

    总结:Java 集合进阶精讲1

    总结:Java 集合进阶精讲2-ArrayList

     

    集合进阶1---为集合指定初始容量

    集合在Java编程中使用非常广泛,当容器的量变得非常大的时候,它的初始容量就会显得很重要了.

    因为扩容是需要消耗大量的人力物力财力的。

    同样的道理,Collection的初始容量也显得异常重要。所以:对于已知的情景,请为集合指定初始容量。

    import java.util.ArrayList;
    import java.util.List;
    
    
    public class ColTest {
    
        public static void main(String[] args) {  
            Base_User baseUser = null;  
            long begin1 = System.currentTimeMillis();  
            List<Base_User> list1 = new ArrayList<Base_User>();  
            for(int i = 0 ; i < 1000000; i++){  
                baseUser = new Base_User(i,"chenssy_"+i,i);  
                list1.add(baseUser);  
            }  
            long end1 = System.currentTimeMillis();  
            System.out.println("list1 time:" + (end1 - begin1));  
              
            long begin2 = System.currentTimeMillis();  
            List<Base_User> list2 = new ArrayList<>(1000000);  
            for(int i = 0 ; i < 1000000; i++){  
                baseUser = new Base_User(i,"chenssy_"+i,i);  
                list2.add(baseUser);  
            }  
            long end2 = System.currentTimeMillis();  
            System.out.println("list2 time:" + (end2 - begin2));  
        }  
        
    }

    分析:

    插入1000000条数据,list1没有没有申请初始化容量,而list2初始化容量1000000。运行结果我们可以看出list2的速度是list1的两倍左右。

    ArrayList的扩容机制是比较消耗资源的。我们先看ArrayList的add方法:

    public boolean add(E e) {    
            ensureCapacity(size + 1);     
            elementData[size++] = e;    
            return true;    
        }    
          
        public void ensureCapacity(int minCapacity) {    
            modCount++;         //修改计数器  
            int oldCapacity = elementData.length;      
            //当前需要的长度超过了数组长度,进行扩容处理  
            if (minCapacity > oldCapacity) {    
                Object oldData[] = elementData;    
                //新的容量 = 旧容量 * 1.5 + 1  
                int newCapacity = (oldCapacity * 3)/2 + 1;    
                    if (newCapacity < minCapacity)    
                        newCapacity = minCapacity;    
              //数组拷贝,生成新的数组   
              elementData = Arrays.copyOf(elementData, newCapacity);    
            }    
        }  
        

    ArrayList每次新增一个元素,就会检测ArrayList的当前容量是否已经到达临界点,如果到达临界点则会扩容1.5倍。

    然而ArrayList的扩容以及数组的拷贝生成新的数组是相当耗资源的。

    大数据量的前提下,指定初始化容量,效率的提升和资源的利用会显得更加具有优势。

    集合进阶2---使用entrySet遍历Map集合KV

    HashMap的遍历有两种常用的方法,那就是使用keyset及entryset来进行遍历

    但两者的遍历速度是有差别的。

    第一种: entryset 效率高

    Map map = new HashMap(); 
    Iterator iter = map.entrySet().iterator(); 
    while (iter.hasNext()) { 
        Map.Entry entry = (Map.Entry) iter.next(); 
        Object key = entry.getKey(); 
        Object val = entry.getValue(); 
    } 

    第二种: keySet 效率低

    Map map = new HashMap(); 
    Iterator iter = map.keySet().iterator(); 
    while (iter.hasNext()) { 
        Object key = iter.next(); 
        Object val = map.get(key); 
    } 

    对于keySet其实是遍历了2次,一次是转为iterator,一次就从hashmap中取出key所对于的value。

    而entryset只是遍历了第一次,他把key和value都放到了entry中,所以就快了。

    集合进阶3---合理利用集合的稳定性和有序性

    合理利用集合的稳定性(order)和有序性(sort),避免集合的无序性和不稳定性带来的负面影响。

    • 稳定性指集合每次遍历的元素次序是一定的。
    • 有序性是指遍历的结果按某种比较规则依次排序的。

    ArrayList是order/unsort,HashMap是unorder/unsort,TreeSet是order/sort,还可以通过TreeSet结合ArrayList对结果进行排序。

    Java 常用集合的一些特征:

    • ①、LinkedList 底层是双向链表。ArrayList:底层采用数组结构,里面添加的元素有序可以重复。

    • ②、HashSet:底层采用哈希表算法,里面添加的元素无序不可重复。

    • ③、HashMap:底层也是采用哈希表算法,但是里面添加的元素是 key-value 的形式。key 不允许重复,value 可以。

    如何好好利用这些集合的原理,简化我们的编程呢。

    1、统计一字符串中每个字符出现的次数?

    解析:给定一串字符串,统计每个字符出现的次数。统计的字符是不能重复的,而出现的个数我们可以不用管。那么很容易联想到 Map 的集合原理,key-value。我们将统计的字符放在 Map<Character,Integer>中是一种很好的实现方式。

    HashMap

    import java.util.HashMap;
    import java.util.Map;
    
    
    public class CnTest {
    
         public static Map<Character, Integer> countChar(Map<Character, Integer> map,String str){
                //将所给的字符串解析为一个字符构造的数组
                char[] chars = str.toCharArray();
                 
                for(char c : chars){
                    if(map.containsKey(c)){
                        int oldCount = map.get(c);
                        map.put(c, oldCount+1);
                    }else{
                        map.put(c, 1);
                    }
                }
                 
                return map;
            }
         
            public static void main(String[] args) {
                String str = "hello world";
                //定义一个 Map 集合,用来存放统计的     字符--个数
                Map<Character, Integer> hashMap = new HashMap<Character, Integer>();
                System.out.println(countChar(hashMap,str));
                //{w=1, d=1,  =1, e=1, r=1, o=2, l=3, h=1}
            }
    }

    补充:这里我们用来保存统计字符的是 HashMap 的实现类,这里打印出来的字符统计是无序的。

    LinkedHashMap

    根据字符串给定的顺序有序的统计出

             public static void main(String[] args) {
                String str = "hello world";
                //定义一个 Map 集合,用来存放统计的     字符--个数
                Map<Character, Integer> linkedHashMap = new LinkedHashMap<Character, Integer>();
                System.out.println(countChar(linkedHashMap,str));
                //{h=1, e=1, l=3, o=2,  =1, w=1, r=1, d=1}
             }

    TreeMap

    用 uicode 的编码顺序打印给定的字符串

         public static void main(String[] args) {
                String str = "hello world";
                //定义一个 Map 集合,用来存放统计的     字符--个数
                Map<Character, Integer> treeMap = new TreeMap<Character, Integer>();
                System.out.println(countChar(treeMap,str));
                //{ =1, d=1, e=1, h=1, l=3, o=2, r=1, w=1}
         }

    二、去掉给定数组重复的数据?

    解析:将数组中的元素都放到Set,然后将 Set 集合转变为数组就可以了。

    import java.util.HashSet;
    import java.util.Set;
    
    
    public class CrTest {
    
        
        public static Integer[] clearRepeat(int [] array){
            Set<Integer> set = new HashSet<Integer>();
            for(int i : array){
                set.add(i);
            }
            Integer[] newArray = set.toArray(new Integer[set.size()]);
            return newArray;
        }
         
         
        public static void main(String[] args) {
            //创建一个数组,可以看出 2和4 是重复的
            int [] array = {1,2,3,4,2,2,3,4};
            Integer[] newArray = clearRepeat(array);
            for(Integer i : newArray){
                System.out.println(i);
            }
            //1 2 3 4
             
        }
    }

    同理我们可以改变 Set 集合的实现类,hashSet 是无序的,我们可以会用** LinkedHashSet** 保证既定顺序;TreeSet 保证自然顺序

    over

    by:一只阿木木

  • 相关阅读:
    Java集合学习(8):LinkedList
    Java集合学习(7):ArrayList
    Java集合学习(6):LinkedHashSet
    数据结构与算法19—排序
    ZooKeeper基本介绍
    Java集合学习(5):LinkedHashMap
    Java集合学习(4):HashTable
    Java集合学习(3):HashSet
    java集合学习(2):Map和HashMap
    HTML DOM的创建,删除及替换
  • 原文地址:https://www.cnblogs.com/yizhiamumu/p/9157335.html
Copyright © 2011-2022 走看看