美文网首页
重拾Java(五)集合

重拾Java(五)集合

作者: h2coder | 来源:发表于2019-02-24 16:12 被阅读0次

    重拾Java第五篇-集合

    • 集合,数据的容器,每天都用,来来来,复习一下

    为什么要用集合,数组不可以吗

    • 数组存储数据没错可以,但是数组一旦指定了长度就不能超过,当数据未知个数时,就有点麻烦啦~

    集合和数组有什么不一样吗?

    • 数组的元素的数据类型,即可以是基本数据类型,也可以是对象。而集合则只能是对象,所以需要存储基本数据类型时,就要存储他们的包装类,例如要存储int类型,对应的包装类为Integer类型。

    集合的分类

    Collection集合体系.png Map集合体系.png
    • 集合根接口

      • Collection
      • Map,键值对,具有映射关系的数据
    • 根接口的子接口,其中Map没有子接口,而直接是实现。

      • Collection
        • List,有序,可重复
        • Set,无序,不可重复
    • List接口的常用实现类

      • ArrayList,底层为数组实现
      • LinkedList,底层为双向联表实现
      • Vector,可以理解为线程安全的的ArrayList,ArrayList是线程不安全的
      • CopyOnWriteArrayList,JDK1.5-concurrent包中增加的针对并发而设计的List接口实现类
    • Set接口的常用实现类

      • HashSet,底层为哈希表,无序,不可重复,如重复,新值会覆盖旧值
      • LinkedHashSet,底层为链表实现的哈希表,有序,不可重复
      • TreeSet,底层为红黑树,整体记录会按指定规则排序
      • CopyOnWriteArraySet,和CopyOnWriteArrayList类似,但实现的是Set接口。
    • Map接口的常用实现类

      • HashMap,底层为哈希表,键值对。无序,最多只允许一条记录的key值为Null(多条会覆盖),允许多条记录的Value为Null,非同步的。
      • LinkedHashMap,底层为链表实现的哈希表。键值对,有序。
      • TreeMap,底层为红黑树,键值对,整体记录会按指定规则排序
      • Hashtable,和HashMap类似,不同的是,Key和Value均不可为Null,并且他是线程安全的,所以性能会比较低。
      • ConcurrentHashMap,应对并发设计的Map实现。

    List集合实现类的异同

    • ArrayList,底层为数组实现,所以存储空间是连续的,做查询时会比较快。但是做插入、删除时,每次都需要挪动数组元素,所以会比较慢。

    • LinkedList,底层为双向链表,链表元素之间头尾相接,做插入时只要找到前面的元素,再将当前元素接上尾部,再找后面的元素,接上头部即可,所以插入、删除速度会比较快。而查询时,内存地址不一定是连续的,所以查找会比较慢。

    • Vector,可以理解为线程安全的的ArrayList,他的增删查改都加了synchronized关键字保证线程安全,但是损耗了性能,现在一般不使用它,而使用Collections工具类调用synchronizedList进行包装(实质也是用了装饰者模式将增删改查方法加上synchronized关键字保证线程安全)。

    • CopyOnWriteArrayList,针对并发而设计的List接口实现类,多用于读多写少的场景,顾名思义就是在写的操作的时候,copy一份数据到新的容器,再将引用指向新的容器引用,整个过程是加锁实现线程安全的,而读是不加锁的。

    • 总结

      • 单线程 读的操作比较多,一般使用ArrayList,增删操作比较多使用LinkedList。

      • 多线程,Collections工具类调用synchronizedList包装List实现,Vector不推荐使用了。

      • 高并发场景,CopyOnWriteArrayList读写分离解决并发问题。

    Set集合实现类的异同

    • HashSet,底层为哈希表,无序,不能存储重复元素,如重复,新值会覆盖旧值,哈希表生成索引,速度比较快。不关心顺序,需要排除重复时使用。

    • LinkedHashSet,底层为链表实现的哈希表,有序,不可重复,当需要不重复,并且有序的场景时使用。

    • TreeSet,底层为红黑树,可以插入后,进行排序,当需要插入后,不是按插入顺序排序,而是需要一定规则排序时使用,例如数字大小,字母A、B顺序。

    • 总结

      • 单线程

        • 不关心顺序,只需要保证不重复,使用HashSet

        • 需要保证插入时的顺序排序,使用LinkedHashSet

        • 需要全部插入后,整体排序是按指定顺序排序时,使用TreeSet

      • 多线程

        • 当需要保证线程安全时,使用Collections工具类调用synchronizedMap包装Map实现。
      • 高并发

        • 可以使用CopyOnWriteArraySet进行并发处理

    Map集合实现类的异同

    • HashMap,底层为哈希表,键值对。无序,最多只允许一条记录的key值为Null(多条会覆盖),允许多条记录的Value为Null,非同步的。

    • LinkedHashMap,底层为链表实现的哈希表,键值对,有序,key和value均允许为空,非同步的

    • TreeMap,底层为红黑树,键值对,整体记录会按指定规则排序

    • Hashtable,和HashMap类似,不同的是,Key和Value均不可为Null,并且他是线程安全的,所以性能会比较低。

    • ConcurrentHashMap,应对并发设计的Map实现,实现了锁分离,对Hash桶分为18段,在get操作是不加锁,set方式按段加锁

    • 总结

      • 单线程

        • 不关心顺序,只需要保证不重复,使用HashMap

        • 需要保证插入时的顺序排序,使用LinkedHashMap

        • 需要全部插入后,整体排序是按指定顺序排序时,使用TreeMap

      • 多线程

        • 当需要保证线程安全时,使用Collections工具类调用synchronizedMap包装Map实现。
      • 高并发

        • 可以使用ConcurrentHashMap进行并发处理

    常用集合操作API

    • boolean add(Object o);
      向集合中插入数据,如果集合对象被添加操作改变了返回true。就是说插入成功了。

      ArrayList<String> list = new ArrayList<>();
              list.add("Wally");
      
    • boolean addAll(Collection
      c);,将另外一个集合c的所有元素添加到指定集合,操作成功了返回true。

      ArrayList<String> list = new ArrayList<>();
      ArrayList<String> list2 = new ArrayList<>();
      list2.add("Barry");
      list.addAll(list2);
      
    • void clear();清空集合元素,集合长度为0。

      ArrayList<String> list = new ArrayList<>();
      list.add("Barry");
      list.clear();
      
    • boolean contains(Object o),判断集合是否包含了指定元素。

      ArrayList<String> list = new ArrayList<>();
      String name = "Barry";
      list.add(name);
      list.contains(name);
      
    • boolean containsAll(Collection c),判断集合是否包含了指定集合c中的所有元素。

      ArrayList<String> list = new ArrayList<>();
      ArrayList<String> list2 = new ArrayList<>();
      String name = "Barry";
      list.add(name);
      list2.add(name);
      list2.add("Wally");
      list2.containsAll(list);
      
    • boolean isEmpty(),判断集合是否为空,长度为0返回true,否则返回false。

      ArrayList<String> list = new ArrayList<>();
      list.isEmpty();
      
    • boolean remove(Object
      o),从集合中移除指定元素,如果集合中有多个元素匹配,只会删除第一个匹配的元素。操作成功返回true,否则为false。

      ArrayList<String> list = new ArrayList<>();
      String name = "Barry";
      list.add(name);
      list.remove(name);
      
    • boolean removeAll(Collection c),从集合中移除指定集合c中所有的元素。

      ArrayList<String> list = new ArrayList<>();
      String name = "Barry";
      //[Barry]
      list.add(name);
      ArrayList<String> list2 = new ArrayList<>();
      list2.add(name);
      //[Barry, wally]
      list2.add("Wally");
      //移除后[Wally]
      list2.removeAll(list);
      
    • boolean retainAll(Collection
      c),从集合中移除指定集合c中不包含的元素。相当于只保留了2个集合的交集部分。

      ArrayList<String> list = new ArrayList<>();
      String name = "Barry";
      //[Barry]
      list.add(name);
      ArrayList<String> list2 = new ArrayList<>();
      list2.add(name);
      //[Barry, wally]
      list2.add("Wally");
      //只保留2个集合的交集部分,就只有[Barry]
      list2.retainAll(list);
      

    特殊集合才有的API

    • ArrayList
    • 按角标进行查找元素
      ArrayList<String> list = new ArrayList<>();
      list.add("Barry");
      //Barry
      String result = list.get(0);
    
    • 按角标删除元素
    ArrayList<String> list = new ArrayList<>();
    list.add("Barry");
    list.remove(0);
    
    • 角标遍历
    ArrayList<String> list = new ArrayList<>();
    list.add("Barry");
    list.add("Wally");
    list.add("Lucy");
    for (int i = 0; i < list.size(); i++) {
        String element = list.get(i);
        System.out.println("element " + element);
    }
    

    Map集合API

    • 增加元素
    HashMap<String, Integer> map2 = new HashMap<>();
    map.put("Barry", 22);
    map.putAll(map2);
    
    • 移除元素
    HashMap<String, Integer> map2 = new HashMap<>();
    map.put("Barry", 22);
    map.remove("Barry");
    
    • 获取所有的Key集合
    HashMap<String, Integer> map2 = new HashMap<>();
    map.put("Barry", 22);
    Set<String> keySet = map.keySet();
    
    • 获取所有Value的集合
    HashMap<String, Integer> map2 = new HashMap<>();
    map.put("Barry", 22);
    Collection<Integer> values = map.values();
    
    • 判断某个Key是否在集合中
    HashMap<String, Integer> map2 = new HashMap<>();
    map.put("Barry", 22);
    boolean isContains = map.containsKey("Barry");
    
    • 判断某个Value是否存在于集合中
    HashMap<String, Integer> map2 = new HashMap<>();
            map.put("Barry", 22);
            boolean isContainsValue = map.containsValue(18);
    
    • 遍历
    HashMap<String, Integer> map2 = new HashMap<>();
    map.put("Barry", 22);
    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        String key = entry.getKey();
        Integer value = entry.getValue();
    }
    

    相关文章

      网友评论

          本文标题:重拾Java(五)集合

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