美文网首页
重拾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