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

前言:因为看到网上关于循环遍历,好多博客内容都比较少,要么只说了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 调用被装饰对象的操作方法。

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

    原文作者:架构
    原文地址: https://www.jianshu.com/p/dd348a1fa51f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞