美文网首页面试有空就看看Android知识
遍历ArrayList,HashSet,HashMap。(全面)

遍历ArrayList,HashSet,HashMap。(全面)

作者: 半盏茶灯 | 来源:发表于2017-01-25 18:09 被阅读644次

    前言:因为看到网上关于循环遍历,好多博客内容都比较少,要么只说了list,要么只说了set或者map,我想整理一下,所以就把几个整理到一起。也做了一些总结,希望对大家也有所帮助。以下demo的完整代码可以在github上面下载(链接地址)

    (一)遍历List

            List<String> list = getArrayList();
            /**
             * 方式一,使用for循环
             */
            for (int i = 0, len = list.size(); i < len; i++) {
                String s = list.get(i);
                System.out.println(s);
            }
    
            /**
             * 方式二,使用增强for循环
             */
            for (String s : list) {
                System.out.println(s);
            }
    
            /**
             * 方式三,使用for和Iterator
             */
    
            for(Iterator<String> iterator = list.iterator(); iterator.hasNext();){
                String value = iterator.next();
    
                System.out.println(value);
            }
    
            /**
             * 方式四,使用while和Iterator(效率和方式3一样)
             */
            Iterator<String> iterator = list.iterator();
            while (iterator.hasNext()){
                String s = iterator.next();
                System.out.println(s);
            }
    
        /**
         * 生成一个List,用于遍历
         * @return 生成的List
         */
        public static List<String> getArrayList() {
            List<String> list = new ArrayList<>();
    
            list.add("aa");
            list.add("bb");
            list.add("cc");
            list.add("dd");
    
            return list;
        }
    

    PS:
      以上就是List遍历的4种方式。

    • 个人认为对于android来说,数据量都不会很大,效率都差不多,自己哪个方便就用哪种。
    • 理论上,方式1是最快的,但是需要考虑并发问题。而如果要进行删除操作,就只能用iterator。
    • foreach 和for:foreach 只能从头到尾,不可以从后面开始遍历。foreach遍历的时候不能给迭代变量赋值(可以给迭代变量里面的内容),比如你不可以修改User引用,可以通过该引用修改User内部数据。

    (二)遍历HashSet

        public static void main(String[] args) {
    
            Set<String> set = getHashSet();
            /**
             * 方式1,增强for循环
             */
            for (String value : set) {
                System.out.println(value);
            }
            /**
             * 方式2,使用迭代器Iterator
             */
            Iterator<String> iterator = set.iterator();
            while (iterator.hasNext()) {
                String value = iterator.next();
                System.out.println(value);
            }
    
            /**
             * 方式3,使用for和迭代器Iterator,和方式2一样,写法不一样而已
             */
            for (Iterator<String> iterator2 = set.iterator(); iterator2.hasNext(); ) {
                String value = iterator.next();
                System.out.println(value);
            }
    
    
        }
    
        /**
         * 生成一个Set<String>,用于遍历
         *
         * @return 生成的Set<String>
         */
        public static Set<String> getHashSet() {
            Set<String> set = new HashSet<>();
            set.add("aa");
            set.add("bb");
            set.add("cc");
            return set;
        }
     
    

    PS:
      set可以添加null元素,不能添加重复的元素(重复元素以hashCodeequals作为判断依据),当add(Object)的时候,如果set不存在和Object的hashCode一样的元素就直接add.如果存在就会调用equals方法比较两个元素,如果返回true,就当作相同元素,否则当作不同元素,添加元素到集合。具体添加重复元素验证可以参考案例的CollectionsDemo,修改Student类即可验证。

    (三)遍历Map

        public static void main(String[] args) {
            Map<String, String> map = getHashMap();
    
            /**
             * 方式1,使用for-each。
             */
            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue());
            }
    
            /**
             *方式2,使用Iterator遍历(使用泛型)
             */
            Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, String> entry = iterator.next();
                System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue());
            }
    
            /**
             *方式3,使用Iterator遍历(不使用泛型)
             */
            Iterator iterator1 = map.entrySet().iterator();
            while (iterator1.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator1.next();
                System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue());
            }
    
            /**
             * 方式4,通过键遍历(效率低)
             */
            for (String key : map.keySet()) {
                String value = map.get(key);
                System.out.println("key:" + key + ",value:" + value);
            }
    
            /**
             * 方式5,只需要key集合或者value集合时候使用
             */
            for (String key : map.keySet()) {
                System.out.println("key:" + key);
            }
    
            for (String value : map.values()) {
                System.out.println("value:" + value);
            }
    
        }
    
        /**
         * 生成一个Map<String, String>,用于遍历
         *
         * @return Map<String, String>
         */
        public static Map<String, String> getHashMap() {
            Map<String, String> map = new HashMap<>();
            map.put("a", "a_value");
            map.put("b", "b_value");
            map.put("c", "c_value");
            return map;
        }
    

    PS:
    map一般都使用Iterator遍历或者for-each遍历

    总结

    1. 遍历删除问题
      遍历的时候要使用删除的话,直接使用集合引用进行删除操作会抛ConcurrentModificationException异常,
      需要调用Iterator的remove方法才行。例子:{@link ListTraverseDemo#testTraverseRemove()}
    1. 添加元素问题
      set不能添加重复的元素(重复元素以hashCode和equals作为判断依据),当add(Object)的时候,如果set不存在和Object的hashCode一样的元素就直接add.
      map 添加存在相同key的时候,其value会覆盖前面的value。
    2. 是否可以添加null元素
      list和set可以,map的key和value都可以,

    PS:set内部是使用map实现的,存放元素的使用,set的value将作为map的key,set引用作为map的value。

    1. 线城安全问题
      ArrayList,HashMap,HashSet 都是不安全的。可以使用Collections中的方法转成安全类型的集合:
      synchronizedMap(map),synchronizedList(list),synchronizedSet(set)。

    PS:内部其实是使用了 装饰模式:继承了该集合类,增强方法,重写操作的方法中使用了synchronized 调用被装饰对象的操作方法。

    我只是粗略总结一下主要注意点,能力有限,如有不当之处,如有欢迎各位指正,如有容易忽略和容易犯错的注意点需要补充也欢迎提出。

    相关文章

      网友评论

      本文标题:遍历ArrayList,HashSet,HashMap。(全面)

      本文链接:https://www.haomeiwen.com/subject/oeatittx.html