Java深入学习-Java集合框架(一)Collection

Java集合框架-Collection及三大子类

Java集合框架具体实现关系

  • 由点组成的方框表示接口
  • 由小段线组成的方框表示抽象类
  • 由实线组成的方框表示实体类

Collection

元素集合的总接口,定义了一些基本的增删改查等方法

  • 抽象方法:

    | Modifier and Type | 方法 | 描述 |
    | —————– | ————————————- | —————————————— |
    | boolean | add(E e) | 在集合中增加指定元素 |
    | boolean | addAll(Collection<? extends E> c) | 将指定集合中所有元素添加到此集合中 |
    | void | clear() | 删除集合中所有元素 |
    | boolean | contains(Object o) | 如果集合中包含指定元素则返回true |
    | boolean | containsAll(Collection<?> c) | 如果集合中包含指定集合中所有元素则返回true |
    | boolean | equals(Object o) | 将指定对象与此集合进行比较相等则返回true |
    | int | hashCode() | 返回此集合的哈希码 |
    | boolean | isEmpty() | 如果此集合不包含任何元素则返回true |
    | Iterator<E> | iterator() | 返回此集合中元素的迭代器 |
    | boolean | remove(Object o) | 从此集合中移除指定元素的单个实例 |
    | boolean | removeAll(Collection<?> c) | 删除集合中指定集合的所有元素 |
    | boolean | retainAll(Collection<?> c) | 仅保留集合中指定集合的所有元素 |
    | int | size() | 返回此集合中的元素数 |
    | Object[] | toArray() | 返回包含此集合中所有元素的Object数组 |
    | <T> T[] | toArray(T[] a) | 返回包含此集合中所有元素的T类数组 |

    其中toArray()和toArray(T[] a)的差别在于:

    • toArray():返回的是Object数组不能将整个Object数组强制类型转换成另一种类型的数组,若需要转换需要遍历数组进行,否则会造成java.lang.ClassCastException异常

    • toArray(T[] a):返回的是a引用指向的T类型的数组(具体可看ArrayList的toArray实现,即若a指向的数组长度小于集合中的元素个数,会产生新的数组实例返回而不是返回a引用指向的数组实例),具体操作为将集合中所有元素复制到a引用指向的T类型的数组中,然后返回T类型数组的引用

      1
      2
      //实际使用方法 collection为某个集合类实例 使用toArray转换成String类型数组
      String[] array=collection.toArray(new String[collection.size()]);
  • 默认(拓展)方法:Java 8允许我们给接口添加非抽象的方法实现,只需要使用default关键字,接口中的非抽象方法又称为拓展方法

    | 修饰符和返回类型 | 方法 | 描述 |
    | ———————— | —————————————– | ———————————————— |
    | default Stream<E> | parallelStream() | 返回一个此集合的并行Stream Source |
    | default boolean | removeIf(Predicate<? super E> filter) | 移除集合中满足指定Predicate的元素 |
    | default Spliterator<E> | spliterator() | 返回一个可分割迭代器,用于并行遍历数据源中的元素 |
    | default Stream<E> | stream() | 返回一个此集合的Stram Source |

    • removeIf:删除集合中满足filter指定条件的元素

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      //源代码 本质为实现Predicate接口的【boolean test】方法,根据操作的返回值决定是否移除元素
      default boolean removeIf(Predicate<? super E> filter) {
      Objects.requireNonNull(filter);
      boolean removed = false;
      final Iterator<E> each = iterator();
      while (each.hasNext()) {
      if (filter.test(each.next())) {
      each.remove();
      removed = true;
      }
      }
      return removed;
      }
      //使用方法 根据 返回布尔值 决定是否移除元素
      ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
      list.removeIf(str-> str.length()>3);
      System.out.println(list);
      //输出:[I, you, too]
    • Java 8新增的Stream Source用法会在后面章节讲解

  • 继承方法:Collection类继承了java.lang.Iterable类,其中包含了一个方法void forEach(Consumer<? super E> action),对集合执行accept操作,不用操作结果替换原来的元素,一般采用Lambda表达式使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //源代码 本质为实现其Consumer接口的【void accept】方法,然后对每个集合元素调用accept方法
    default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
    action.accept(t);
    }
    }
    //使用方法 无返回值
    ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
    list.forEach( str-> {
    if(str.length()>2) System.out.println(str.toUpperCase());
    });
    //输出:
    //LOVE
    //YOU
    //TOO

Set

Set集合表示一个不允许包含重复元素的集合,继承Collection接口并没有提供额外的方法,只是有一个特性:若将两个相同的元素加入到同一个Set集合中,则add()操作失败返回false且新元素不会被加入

List

List集合表示一个可通过索引访问指定元素的有序可重复的集合,默认按照元素的添加顺序设置元素的索引。

List接口继承Collection接口,因此有Collection的所有抽象方法,但由于List是有序集合(索引顺序),因此List接口增加了一些根据索引来操作集合的方法

  • 抽象方法:

    | 修饰符和类型 | 方法 | 描述 |
    | —————– | ———————————————— | ———————————————————— |
    | void | add(int index, E element) | 将指定元素插入集合的指定位置 |
    | boolean | addAll(int index, Collection<? extends E> c) | 将指定集合的所有元素插入此集合的指定位置 |
    | E | get(int index) | 返回集合指定位置的元素 |
    | int | indexOf(Object o) | 返回集合中第一次出现指定元素的索引,若集合中不存在该元素则返回-1 |
    | int | lastIndexOf(Object o) | 返回集合中最后一次出现指定元素的索引,若集合中不存在该元素则返回-1 |
    | ListIterator<E> | listIterator() | 返回集合的List迭代器 |
    | ListIterator<E> | listIterator(int index) | 返回从集合指定位置开始的List迭代器 |
    | E | remove(int index) | 删除集合指定位置的元素 |
    | E | set(int index, E element) | 用指定元素替换集合指定位置的元素 |
    | List<E> | subList(int fromIndex, int toIndex) | 返回[fromIndex,toIndex)之间的子集合 |

  • 默认(拓展)方法:增加了两个拓展方法和重写了Collection的spliterator()默认方法

    | 修饰符和类型 | 方法 | 描述 |
    | ————– | —————————————– | ————————————– |
    | default void | replaceAll(UnaryOperator operator) | 根据operator参数重新设置集合的所有元素 |
    | default void | sort(Comparator<? super E> c) | 根据Comparator参数对集合的元素进行排序 |

    • replaceAll:对每个元素执行operator操作,并用操作结果替换原来元素

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      //源代码 本质为实现UnaryOperator接口的【T apply】方法并将结果替换原来的元素
      default void replaceAll(UnaryOperator<E> operator) {
      Objects.requireNonNull(operator);
      final ListIterator<E> li = this.listIterator();
      while (li.hasNext()) {
      li.set(operator.apply(li.next()));
      }
      }
      //使用方法
      ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
      list.replaceAll(str->{
      if(str.length()>3) return str.toUpperCase();
      else return str;
      });
      System.out.println(list);
      //输出:[I, LOVE, you, too]
    • sort:根据Comparator对集合元素进行排序,并用排序结果替换原来的集合排序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      //源代码 本质为实现Comparator的【int compare(T o1,T o2)】方法,创建一个实例集合存储排序后的值,之后遍历实例数组将其复制到原集合中
      default void sort(Comparator<? super E> c) {
      Object[] a = this.toArray();
      Arrays.sort(a, (Comparator) c);
      ListIterator<E> i = this.listIterator();
      for (Object e : a) {
      i.next();
      i.set((E) e);
      }
      }
      //使用方法
      ArrayList<String> list = new ArrayList<>(Arrays.asList("I", "love", "you", "too"));
      list.sort((str1,str2)->str2.length()-str1.length());
      System.out.println(list);
      //输出:[love, you, too, I]

Queue

Queue集合是一个FIFO(先进先出)的队列集合,新元素插入(offer)到队列尾部,访问元素(poll)返回队列头部,通常不允许随机访问队列中的元素

List接口继承Collection接口,因此有Collection的所有抽象方法,但由于Queue是队列集合,因此Queue接口重写了add方法并且提供了一些队列特性的方法

  • 抽象方法:
修饰符和类型 方法 描述
boolean add(E e) 将元素插入队列,成功返回true,超过队列容量限制则抛出IllegalStateException异常
boolean offer(E e) 将元素插入队列,成功返回true,超过队列容量限制返回false
E peek() 获取但不移除队列头部元素,队列为空返回null
E poll() 获取并移除队列头部元素,队列为空返回null
E element() 获取但不移除队列头部元素,队列为空抛出NoSuchElementException异常
E remove() 获取并移除队列头部元素,队列为空抛出NoSuchElementException异常