Java8中Collection的体系结构

序言

  • 这章笔记,只要讲述jdk8中关于Collection的知识,例如,Collection的体系结构,Set,List,Map等抽象接口的区别,和其具体的implement

1.接口

1.1Collection的体系结构

  1. 图例[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0xF5xcx-1602060161785)(E:\typora\image\image-20200812151334631.png)]
  2. 补充说明
    • Colleciton接口是其他collection接口的父接口,该接口代表着一组元素(数据接口),并且定义一些方法,可以对这些数据进行访问,遍历,操作等
    • Set接口其表示的是不可重复,无序的collecion类型,该接口可以表示例如线程等的抽象,其可以利用其的一些方法,来进行数论的操作(例如:并,交,差等),SortedSet接口,继承Set接口,其主要的功能可以对元素进行排序(不过要注意的是,该集合中的元素要实现Comparable接口,在comparableTo方法中指定比较大小的规则,或者提供Comparator类)
    • List接口是可重复,有序的collection类型,其可以进行位置的操作,例如对搜索出某元素的index,或者可以替换某index上的元素
    • 所有有关Collection接口的实现类都需要提供一个构造函数,该参数为Collection类型,目的是提供不同类型的Colleciton接口,或者不同实现类之间的相互转换,例如Set接口的实现类可以转化为List接口实现类,HashSet转化为TreeSet
    • Map接口表示一组保存键值对的数据的容器,注意的是,其key不可重复,所以一个key最多只能映射一位value
    • SortedMap接口跟SortedSet的接口差不多,注意的地方也是key元素需要实现Comparable或者提供Comparator
    • 所有有关Map接口的实现类都需要提供一个构造函数,该参数为Map类型,目的是提供Map实现类之间的相互转化

1.2 Collecitoninterface

  1. 说明:

    • 该节说明Collecion接口中定义哪些基本的方法,这些方法可以进行哪些操作

    • Colleciton定义的方法,由于其他关于collection的实现类继承该接口,所以这些方法一般为通用的

  2. 基本的操作

    • int size(), boolean isEmpty(), boolean contains(Object element), boolean add(E element), boolean remove(Object element), and Iterator iterator()

    • add方法如果添加成功,则返回true,如果不添加成功,则放回false**(问题:如果元素的对象,应该加入的是对象的地址**),该方法在不同类型的colleciton中会有不同的行为

    • remove方法删除的是当前的元素,(问题:当前元素应该指的是cursor,即光标指定的元素吧),该方法在不同类型的colleciton中会有不同的行为,例如在List中remove一个对象,如果这个对象存在多个,那个其删除的规则又是什么?

    • Collection进行的遍历的方法有三种:聚合操作,for-each操作和Iterator操作

      1. //聚合操作
        myShapesCollection.stream()
        .filter(e -> e.getColor() == Color.RED)
        .forEach(e -> System.out.println(e.getName()));
        
        String joined = elements.stream()
            .map(Object::toString)
            .collect(Collectors.joining(", "));
        
        int total = employees.stream()
        .collect(Collectors.summingInt(Employee::getSalary)));
        
        //for-each操作
            String joined = elements.stream()
            .map(Object::toString)
            .collect(Collectors.joining(", "));
        
        //迭代操作
        static void filter(Collection<?> c) {
            for (Iterator<?> it = c.iterator(); it.hasNext(); )
                if (!cond(it.next()))
                    it.remove();
        }
        
        //我们可以看到,在聚合操作和for-each操作对集合进行遍历的期间,不可对集合进行add,remove等操作,但iterator则可以进行remove操作,这样可以进行过滤操作,但注意的是,该remove只能在调用next()方法之后进行调用,其删除的元素是next()返回的那个元素
        
  3. 批操作

    • containsAll(Collection c), boolean addAll(Collection c), boolean removeAll(Collection c), boolean retainAll(Collection c), and void clear().
    • retainAll方法是删除两个集合中没有的
    • clear方法是删除所有的元素

1.3 Setinterface

  1. 说明

    • Set接口只包含继承来自Collecition中的方法,但在Add方法中则加入一下限制,如不能有重复元素,还有在equalhashCode方法中在实现方法上加入一下stronger contact,例如在比较两个List上,只有它们的元素完全相等,才相等
    • 介绍一下Set该类型接口的用途,例如可以进行数论的操作
    • 该实现类:HashSet, TreeSet,andLinkedHashSet
  2. 操作方法的介绍

    • s1.addAll(s2),->交集
    • s1.retainAll(s2)->并集
    • s1.removeAll(s2)->删除s1中交集(s1和s2的交集)
  3. 用法

    //创建集合
    Collection<Type> noDups = new HashSet<Type>(c);
    
    c.stream()
    .collect(Collectors.toSet()); // no duplicates
    
    //转化为TreeSet
    Set<String> set = people.stream()
    .map(Person::getName)
    .collect(Collectors.toCollection(TreeSet::new));
    
    //注意的是,如果传入进来的colletion中重复的元素(list),在构建set的过程中会自动删除掉重复的元素
    //新创建的集合与原本的集合都是存储着对象的链接,所以一个对象元素内容的更改,会导致另一个集合中的相应的对象元素也修改
    
    //数论的操作
    Set<Type> symmetricDiff = new HashSet<Type>(s1);
    
    //并集
    symmetricDiff.addAll(s2);
    
    Set<Type> tmp = new HashSet<Type>(s1);
    //交集
    tmp.retainAll(s2);
    //得出该集合中只包含s1,s2不同时存在的元素
    symmetricDiff.removeAll(tmp);
    
    

1.4 Listinterface

  1. 说明

    • List接口除了从Colleciton继承的方法外,还额外定义了一下其他方法
      • 位置访问:get,set,add,addAll,remove
      • search:查找某元素的index,方法有:indexOf,lastIndexOf
      • 迭代:listIterator
      • Range-view:subList
    • 两个List相等的标准:元素相等并且顺序也相同
    • List接口的实现类:ArrayList LinkedList
  2. 方法使用

    //添加,注意的是add,addAll,其把元素添加到list集合的末尾
    list1.addAll(list2);
    
    //构建list
    List<String> list = people.stream()
    .map(Person::getName)
    .collect(Collectors.toList());
    
    List<Type> list3 = new ArrayList<Type>(list1);
    list3.addAll(list2);
    
    
     Person  person = new Person("lirisheng",5);
            List<Person> list = new ArrayList<>();
            list.add(person);
            System.out.println(list.indexOf(person));
            list.add(0,new Person("aaa",4));
            System.out.println(list.indexOf(person));
            System.out.println(list);
            list.remove(0);
            System.out.println(list.indexOf(person));
            System.out.println(list);
    //运行结果
       //0
       //1
      //[Person{name='aaa', age=4}, Person{name='lirisheng', age=5}]
      //0
      //[Person{name='lirisheng', age=5}]
    //结果分析
      // lsit中有两个add,一个add(T t),直接加到末尾,另一个add(Int index,T t),加到指定位置
      //某一元素在list中的index,不是固定不变的,而是可能随着某操作而改变
    
    
    //交换
    public static <E> void swap(List<E> a, int i, int j) {
        E tmp = a.get(i);
        a.set(i, a.get(j));
        a.set(j, tmp);
    }
    
    
  3. listIterator

    1. 说明:该接口继承与Iterator,并且额外添加了 hasPrevious and the previous方法

    2. 光标cursor(光标指的位置是两个元素之间

    3. next是返回调用next()方法后,其光标cursor之前的元素,而previous则是返回光标之后的元素

    4. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jlc0lk0v-1602060161790)(E:\typora\image\image-20200812174955667.png)]

      注意:元素的index与cursor的index不一样

    5. 用法

      //注意,listIterator()方法,可以指定初始化光标的位置,如果没有指定,则cursor的index默认为0
      //注意,如果用previous,则其光标的index应该为list.size,即指向list集合的末尾
      for (ListIterator<Type> it = list.listIterator(list.size()); it.hasPrevious(); ) {
          Type t = it.previous();
          ...
      }
      
  4. rang-view

1.5 Map interface

  1. 说明:

    • 该接口表示一组键值对,并且其key值不可重复
    • 定义的方法
      • 基本:put, get, remove, containsKey, containsValue, size, and empty
      • 批操作: putAll and clear
      • collection views: keySet, entrySet, and values
    • 实现类(general-porpuse):HashMap, TreeMap, and LinkedHashMap.
  2. 用法

    // Group employees by department
    Map<Department, List<Employee>> byDept = employees.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment));
    
    // Compute sum of salaries by department
    Map<Department, Integer> totalByDept = employees.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment,
    Collectors.summingInt(Employee::getSalary)));
    
    // Partition students into passing and failing
    Map<Boolean, List<Student>> passingFailing = students.stream()
    .collect(Collectors.partitioningBy(s -> s.getGrade()>= PASS_THRESHOLD)); 
    
    // Classify Person objects by city
    Map<String, List<Person>> peopleByCity
             = personStream.collect(Collectors.groupingBy(Person::getCity));
    
    // Cascade Collectors 
    Map<String, Map<String, List<Person>>> peopleByStateAndCity
      = personStream.collect(Collectors.groupingBy(Person::getState,
      Collectors.groupingBy(Person::getCity)))
        
        
    
  3. collection view

    • 说明:这个概念可以帮助map某些数据映射成Collection(但这个应该不是general-porpuse 实现类),进而可以利用Collection中定义的某些方法,也可以通过利用数论的理论来通过该方法帮助map快速筛选出我们想要得到的map集合

    • 方法:

      • keySet — the Set of keys contained in the Map.
      • values — The Collection of values contained in the Map. This Collection is not a Set, because multiple keys can map to the same value.
      • entrySet — the Set of key-value pairs contained in the Map. The Map interface provides a small nested interface called Map.Entry, the type of the elements in this Set.
    • 用法:

      for (KeyType key : m.keySet())
          System.out.println(key);
      
      // Filter a map based on some 
      // property of its keys.
      for (Iterator<Type> it = m.keySet().iterator(); it.hasNext(); )
          if (it.next().isBogus())
              it.remove();
      
      
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值