简单认识类集

我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储。 而要向存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里,有哪些是容器类呢?

数组和StringBuffer,但是呢?StringBuffer的结果是一个字符串,不一定满足我们的要求,这就是对象数组.

而对象数组又不能适应变化的需求,因为数组的长度固定的,这个时候,为了适应变化的需求,Java就提供了集合类供我们使用。

数组和集合的区别?

 长度区别内容不同元素的数据类型
数组 数组长度固定 数组存储的是同一种类型的元素 数组可以存储基本数据类型,也可以存储引用数据类型
集合 集合长度可变 集合存储的是不同类型的元素 集合只能存储引用类型

在java.util包中定义了所有与类集有关的操作接口:Collection,List,Set,Map,Iteraror和Enumeration。


1.单值保存的最大父接口:Collection[重点]

Collection接口是构造类集框架的基础,是单值数据操作的最大父接口它声明了所有类集都将拥有的核心方法。

所有类集均实现Collection。其中有几种方法可能会引发一个UnsupportedOperationExcepation异常。这些异常将发生在修改不能被修改的类集的时候。当一个对象与另一个对象不兼容,例如企图增加一个不兼容的对象到一个类集中时,将产生一个ClassCastException异常。

编号方法名称描述
1 public boolean add(E e) 增加数据e到调用类集中。
如果e被加入到类集中了,则返回true;
如果此collection不允许有重复元素,并且已经包含了e,则返回false
2 public boolean addAll(Collection c) 将c中所有元素都加入到调用类集中,
如果操作成功(元素被加入了),则返回true,否则返回false
3 public void clear() 从调用类集中删除所有元素
4 public boolean contains(Object obj) 查找数据是否存在
5 public boolean isEmpty() 判断是否为空集合
6 public boolean remove(Object obj) 从调用类集中删除obj的一个实例。
如果这个元素被删除了则返回true,否则返回false
7 public int size() 返回调用类集中元素的个数
8 public Object[] toArray() 将集合变成对象数组
9 public Iterator<E> iterator() 为Iterator接口实例化,迭代器

在Collection接口中一共定义了15个方法,在所有的方法中,只有两个方法最为常用:add()和iterator().

不过开发来讲,很少直接使用Collection,往往都会使用它的子接口:List(允许有重复元素,Set(不允许有重复元素)。

个人推荐:List优先考虑         

此篇略长,如果有需要对javaSE集合类感兴趣的话可以加群 642830685 找管理员免费领取一份JavaSE集合精讲视频。欢迎所有学习java的朋友加群交流学习!

2.允许重复的子接口:List

List(列表)是Collection接口之中最为常见的一个子接口。 List子接口定义:

public interface List<E> extends Collection<E>

List子接口对Collection接口进行了大量的扩充。List接口扩展了Collection并声明存储一系列元素的类集的特性。

编号方法名称描述
1 public void add(int index,Object obj) 将obj插入调用列表,插入位置的下标由index传递。
任何已存在的,在插入点以及插入点之后的元素将后移。
因此没有元素被覆写
2 public Object get(int index) 返回存储在调用类集指定下标处对象
3 public int indexOf(Object obj) 返回调用列表中obj第一次出现的下标。
如果obj不是列表中的元素,则返回-1
4 public int lastIndexOf(Object obj) 返回调用列表中obj最后一次出现的下标。
如果obj不是列表中的元素则返回-1
5 public ListIterator listIterator() ListIterator接口实例化
6 public Object remove(int index) 删除调用列表中index位置的元素并返回删除的元素删除后,
列表被压缩。也就是说被删除元素的后面的元素下标减一
7 public Object set(int index,Object obj) 用obj对调用列表内由index指定的位置进行赋值
8 public List subList(int start,int end) 返回一个列表,该列表包括了调用列表中从start到end-1的元素。
返回列表中的元素也被调用对象引用

由于List本身还属于接口,要想使用接口,就必须知道实现这个接口的子类,在List接口中有两个最为常用的子类:ArrayList,Vector。

(1) 新的子类:ArrayList

ArrayList类扩展AbstractList并执行List接口。ArrayList支持可随需要而增长的动态数组。

public class ArrayList<E> 
	extends AbstractList<E> 
	implements List<E>, RandomAccess, Cloneable, Serializable

在Java中,标准类型的数组是定长的。一旦数组被创建之后,他们不能被加长或缩短,这就意味着开发者必须事先知道数组可以容纳多少元素。一般情况下,只有在运行时才知道需要多大的数组。为了解决这个问题,类集框架定义了ArrayList。本质上,ArrayList是对象引用的一个变长数组。

ArrayList() 
          构造一个初始容量为 10 的空列表。 
ArrayList(Collection<? extends E> c) 
          构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。 
ArrayList(int initialCapacity) 
          构造一个具有指定初始容量的空列表 

示例1:增加数据的操作

package com.shxt.demo01;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayListDemo01 {

    public static void main(String[] args) {
        List<String> allList = null;                // 定义List对象
        Collection<String> allCollection = null;    // 定义Collection对象

        allList = new ArrayList<>();                // 实例化List对象,使用JDK1.7后的泛型声明方式
        allCollection = new ArrayList<String>();    // 实例化Collection,只能是String类型

        allList.add("悟空");                         // 从Collection继承的方法
        allList.add(0,"齐天大圣");    // List接口扩充的方法

        System.out.println(allList);                // 输出结合的内容

        allCollection.add("豹子头");                 // 新增数据
        allCollection.add("林冲");                   // 新增数据

        allList.addAll(allCollection);              // 从Collection继承的方法,增加一组对象
        allList.addAll(0,allCollection);      // List扩充的方法,指定位置增加一组对象

        System.out.println(allList);                 // 输出对象,默认情况下调用toString()方法

    }
}

示例2:删除元素

package com.shxt.demo01;

import java.util.ArrayList;
import java.util.List;

public class ArrayListDemo02 {

    public static void main(String[] args) {
        List<String> allList = new ArrayList<>();

        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");
        allList.add("八戒");
        allList.remove(0);
        System.out.println(allList);    // 删除指定位置的元素
        allList.remove("八戒");       // 删除指定内容的对象
        System.out.println(allList);

    }
}
/*
运行结果:
[八戒, 唐僧, 沙僧, 八戒]
[唐僧, 沙僧, 八戒]
*/

代码说明:

如果使用的是对象集合.例如:List<User> userList = new ArrayList<>();的形式,那么自定义类型User需要重写equals和hashcode方法才能完成对象的删除

示例3:输出List中的内容

package com.shxt.demo01;

import java.util.ArrayList;
import java.util.List;

public class ArrayListDemo03 {

    public static void main(String[] args) {
        List<String> allList = new ArrayList<>();

        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");

        System.out.println("从前向后输出:");
        for (int i = 0; i < allList.size(); i++) {
            System.out.print(allList.get(i)+"	");
        }
        System.out.println("
从后向前输出:");
        for (int i = allList.size()-1; i >=0 ; i--) {
            System.out.print(allList.get(i)+"	");
        }


    }
}
/*
从前向后输出:
悟空	八戒	唐僧	沙僧
从后向前输出:
沙僧	唐僧	八戒	悟空	
 */

示例4:将集合变为对象数组

package com.shxt.demo01;

import java.util.ArrayList;
import java.util.List;

public class ArrayListDemo04 {

    public static void main(String[] args) {
        List<String> allList = new ArrayList<>();

        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");

        String[] array = allList.toArray(new String[]{});//指定泛型的类型
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+"	");
        }

    }
}


示例5:其他方法简单演示

package com.shxt.demo01;

import java.util.ArrayList;
import java.util.List;

public class ArrayListDemo05 {

    public static void main(String[] args) {
        List<String> allList = new ArrayList<>();

        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");
        System.out.println("判断集合是否为空:"+allList.isEmpty());

        System.out.println("是否包含内容:"+allList.contains("八戒"));

        allList.clear();
        System.out.println("判断集合是否为空:"+allList.isEmpty());
        
    }
}


(2) 旧的子类:Vector

Vector是JDK1.0就存在的List子类,使用方式基本一致.

package com.shxt.demo02;

import java.util.List;
import java.util.Vector;

public class VectorDemo01 {
    public static void main(String[] args) {
        List<String> allList = new Vector<>();
        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");

        for (String s  : allList){
            System.out.print(s+"	");
        }
    }
}

(3) ArrayList和Vector子类的区别

编号比较点ArrayListVector
1 性能 采用异步处理方式,性能更高 采用同步处理方式,性能较低
2 线程安全 属于非线程安全的类 属于线程安全的操作类
3 输出方式 只能使用Iterator,Foreach输出 可以使用Iterator,Foreach,Enumeration输出

实际开发中使用推荐使用ArrayList

(4) LinkedList子类和Queue接口

LinkedList表示是一个链表的操作类,Java已经为我们提供了一个链表程序,我们拿来直接使用即可.

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

public interface Deque<E> extends Queue<E> {

下面简单了解一下接口Queue接口,Queue表示是队列操作接口,采用FIFO(先进先出)的方式操作

Queue接口定义的方法

编号方法名称类型描述
1 public E element() 普通 找到链表的表头
2 public boolean offer(E o) 普通 将指定元素增加到链表的结尾
3 public E peek() 普通 找到单不删除链表的头
4 public E poll() 普通 找到并删除此链表的头
5 public E remove() 普通 检索并移除表头

Linked子类扩展的方法

编号方法名称类型描述
1 public void addFirst(E o) 普通 在链表开头增加元素
2 public void addLast(E o) 普通 在链表结尾增加元素
3 public boolean offer(E o) 普通 将指定元素增加到链表的结尾
4 public E removeFirst() 普通 上传链表的第一个元素
5 public E removeLast() 普通 删除链表的最后一个元素

示例1:链表新增数据

package com.shxt.demo02;

import java.util.LinkedList;

public class LinkedListDemo01 {
    public static void main(String[] args) {
        LinkedList<String> allList = new LinkedList<>();
        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");

        System.out.println("初始化数据为:"+allList);

        allList.addFirst("小白龙");
        allList.addLast("白骨精");
        System.out.println("追加数据:"+allList);
        
    }
}

示例2:操作链表头

package com.shxt.demo02;

import java.util.LinkedList;

public class LinkedListDemo02 {
    public static void main(String[] args) {
        LinkedList<String> allList = new LinkedList<>();
        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");

        System.out.println("1.1 element()方法找到表头:"+allList.element());
        System.out.println("1.2 找完表头后的链表内容:"+allList);

        System.out.println("2.1 peek()方法找到表头不删除内容:"+allList.peek());
        System.out.println("2.2 找完表头后的链表内容:"+allList);

        System.out.println("3.1 poll()方法找到表头并删除表头:"+allList.poll());
        System.out.println("3.2 找完表头后的链表内容:"+allList);

    }
}

示例3:ArrayList和LinkedList的效率比较

package com.shxt.demo02;

import java.util.ArrayList;
import java.util.LinkedList;

public class LinkedListDemo03 {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        ArrayList<Integer> list01 = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            list01.add(0,i);
        }
        long end = System.currentTimeMillis();
        System.out.println("ArrayList耗时为:"+(end-start)+"ms");

        start = System.currentTimeMillis();
        LinkedList<Integer> list02 = new LinkedList<>();
        for (int i = 0; i < 100000; i++) {
            list02.addFirst(i);
        }
        end = System.currentTimeMillis();
        System.out.println("LinkedList耗时为:"+(end-start)+"ms");

    }
}
/*
ArrayList耗时为:1304ms
LinkedList耗时为:5ms
*/

3.不允许重复的子接口:Set

Set接口也是Collection接口的子接口,但是与Collection或者List接口不同的是Set接口中不能添加重复的元素.

public interface Set<E>extends Collection<E>

(1) 散列的存放:HashSet

HashSet是Set接口的一个子类,主要的特点是里面不能存放重复元素,而且采用散列的存储方式.所以没有顺序.

package com.shxt.demo03;

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo01 {

    public static void main(String[] args) {
        Set<String> allSet = new HashSet<String>();
        allSet.add("悟空");
        allSet.add("八戒");
        allSet.add("唐僧");
        allSet.add("唐僧");
        allSet.add("唐僧");
        allSet.add("沙僧");

        System.out.println(allSet.toString());
    }
}

(2) 有序的存放:TreeSet

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
package com.shxt.demo03;

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo02 {

    public static void main(String[] args) {
        Set<String> allSet = new TreeSet<>();
        allSet.add("C");
        allSet.add("B");
        allSet.add("C");
        allSet.add("A");
        allSet.add("F");
        allSet.add("G");

        System.out.println(allSet.toString());
    }
}

代码分析:

因为字符串排序规则还相对简单,如果是自定义类型,排序规则就麻烦了,需要重写Comparable接口(可以自学)

(3) SortedSet接口

SortedSet接口继承了Set接口,扩展的方式

编号方法名称类型描述
1 public Comparator<? super E> comparator() 普遍方法 返回与排序相关联的比较器
2 public E first() 普遍方法 返回集合中的第一个元素
3 public SortedSet<E> headSet(E toElement) 普通方法 返回从开始到指定元素的集合
4 public E last() 普通方法 返回集合中的最后一个元素
5 public SortedSet<E> subSet(E fromElement,E toElement) 普通方法 返回指定对象间的元素
6 public SortedSet<E> tailSet(E fromElement) 普通方法 从指定元素的最后
package com.shxt.demo03;

import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSetDemo03 {

    public static void main(String[] args) {
        SortedSet<String> allSet = new TreeSet<>();
        allSet.add("A");
        allSet.add("B");
        allSet.add("C");
        allSet.add("C");
        allSet.add("C");
        allSet.add("D");
        allSet.add("E");

        System.out.println("第一个元素:"+allSet.first());
        System.out.println("最后一个元素:"+allSet.last());
        System.out.println("headSet元素:"+allSet.headSet("C"));
        System.out.println("tailSet元素:"+allSet.tailSet("C"));
        System.out.println("subSet元素:"+allSet.subSet("B","D"));
    }
}

/*
第一个元素:A
最后一个元素:E
headSet元素:[A, B]
tailSet元素:[C, D, E]
subSet元素:[B, C]
*/

4.集合的输出

  • Iterator:迭代输出,是使用最多的输出方式
  • ListIterator:是Iterator的子接口,专门用于输出List中的内容
  • Enumeration:是一个旧的接口,功能与Iterator类似
  • foreach: JDK1.5之后提供,可以输出数组和集合,推荐使用

(1) 迭代输出:Iterator

个人推荐:在使用集合输出时必须形成一个思路,只要碰到了集合输出的操作,就一定要使用Iterator接口,因为这是最标准的做法.Iterator是专门的迭代输出接口,所谓的迭代输出就是将元素一个一个判断,判断其是否有内容,如果有内容则把内容取出.

public interface Iterator<E>{}
编号方法名称类型描述
1 public boolean hashNext() 普通方法 判断是否有下一个元素
2 public E next() 普通方法 取出当前元素
3 public void remove() 普通方法 移除当前元素

示例1:简单示例迭代

package com.shxt.demo03;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo01 {

    public static void main(String[] args) {
        List<String> allList = new ArrayList<>();

        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");
        allList.add("八戒");

        Iterator<String> iterator = allList.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next()+"	");
        }
    }
}

示例2:删除八戒的数据

package com.shxt.demo03;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo01 {

    public static void main(String[] args) {
        List<String> allList = new ArrayList<>();

        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");
        allList.add("八戒");

        Iterator<String> iterator = allList.iterator();
        while (iterator.hasNext()){
           String name = iterator.next();

           if("八戒".equals(name)){
               iterator.remove();//移除
           }
        }
        System.out.println(allList);
    }
}

(2) 双向迭代输出:ListIterator

Iterator 接口的主要功能是由前向后单向输出,如果开发过程中不仅仅是从前往后也可能需要你重后往前输出,那么就需要使用Iterator 的子接口ListIterator,并且扩展了很多方法

编号方法名称类型描述
1 public boolean hashNext() 普通 判断是否有下一个值
2 public E next() 普通 取出当前元素
3 public void remove() 普通 移除当前元素
4 public void add(E o) 普通 将指定元素增加集合
5 public boolean hasPrevious() 普通 判断是否有上一个元素
6 public E previous() 普通 取出当前元素
7 public int nextIndex() 普通 返回下一个元素的索引号
8 public int previousIndex() 普通 返回上一个元素的索引号
9 public void set(E o) 普通 替换元素
package com.shxt.demo03;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo01 {
    public static void main(String[] args) {
        List<String> allList = new ArrayList<>();
        allList.add("悟空");
        allList.add("八戒");
        allList.add("唐僧");
        allList.add("沙僧");

        ListIterator<String> iterator = allList.listIterator();

        System.out.println("由前向后输出:");
        while (iterator.hasNext()){
            String temp = iterator.next();
            System.out.print(temp+",");
        }
        System.out.println();

        System.out.println("由后向前输出:");
        while (iterator.hasPrevious()){
            String temp = iterator.previous();
            System.out.print(temp+",");
        }

    }
}

(3) Foreach

这里就不演示了,集合支持增强for循环

5.Map接口

Collection/Set/List接口都属于单值操作,即每次只能操作一个对象,而Map接口与它们不同的是每次操作的是"一对"对象,即二元偶对象,Map接口的每个每个元素都是使用"key->value"的的键值对形式进行存储,Map接口定义如下:

public interface Map<K,V>
编号方法名称类型描述
1 public void clear() 普通方法 清空Map集合
2 public boolean containsKey(Object key) 普通方法 判断指定的key是否存在
3 public boolean containsValue(Object value) 普通方法 判断指定的value是否存在
4 public Set<Map.Entry<K,V>> entrySet() 普通方法 将Map对象变为Set集合
5 public boolean equals(Object o) 普通方法 对象比较
6 public V get(Object key) 普通方法 根据key取得values
7 public int hashCode() 普通方法 返回哈希码
8 public boolean isEmpty() 普通方法 判断集合是否为空
9 public Set<K> keySet() 普通方法 取得所有的key
10 public V put(K key,V value) 普通方法 想集合中加入元素
11 public void putAll(Map<? extends K,? extends V> t) 普通方法 将一个Map集合中的内容加入到另一个Map
12 public V remove(Object key) 普通方法 根据key删除value
13 public int size() 普通方法 取出集合的长度
14 public Collection<V> values() 普通方法 取出全部的value

(1) 新的子类:HashMap

HashMap : 无序存放的,是行的操作类,key不允许重复

HashMap 本身就是Map的子类,直接使用此类为Map接口进行实例化(接口回调)即可

HashMap类的定义如下:

public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable

实际开发中使用HashMap的频率还是比较高的,我们简单测试一下相关的示例

示例1:集合中增加和获取内容

package com.shxt.demo04;

import java.util.HashMap;
import java.util.Map;

public class Demo01 {

    public static void main(String[] args) {
        Map<String,String> map  = null;
        map = new HashMap<>();
        //增加内容
        map.put("book","西游记");
        map.put("name","吴承恩");
        map.put("type","小说");
        //获取内容
        String value = map.get("book");
        System.out.println("获取的内容是:"+value);

    }
}

发现问题:

发现KEY的类型是Object类型,那么意思是说不仅仅可以使用String作为KEY使用,请注意在实际开发当中大部分是使用String类型作为KEY使用,那么我们测试一下非String的情况

package com.shxt.demo04;

import java.util.HashMap;
import java.util.Map;

public class Demo02 {

    public static void main(String[] args) {
        Map<Object,String> map  = null;
        map = new HashMap<>();
        //增加内容
        map.put(1,"西游记");
        map.put(2,"吴承恩");
        map.put(3,"小说");
        //获取内容
        String value = map.get(2);
        System.out.println("获取的内容是:"+value);

    }
}

再测试更加不合理的代码,纯属娱乐!

package com.shxt.demo04;

import java.util.HashMap;
import java.util.Map;

public class Demo03 {

    public static void main(String[] args) {
        User u1 = new User("林冲");
        User u2 = new User("刘备");


        Map<Object,String> map  = null;
        map = new HashMap<>();
        //增加内容
        map.put(u1,"西游记");
        map.put(u2,"吴承恩");
        //获取内容
        String value = map.get(u2);
        System.out.println("获取的内容是:"+value);

    }
}

class User{
    private String name;

    public User(String name){
        this.name = name;
    }
}

个人当然不推荐这样的使用咯!

示例2:获取所有的KEY和Value

package com.shxt.demo04;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Demo04 {
    public static void main(String[] args) {
        Map<String,String> map  = null;
        map = new HashMap<>();
        //增加内容
        map.put("book","西游记");
        map.put("name","吴承恩");
        map.put("type","小说");

        Set<String> keys = map.keySet();//set集合中存储的key
        Iterator<String> iter = keys.iterator();
        while (iter.hasNext()){
            String key = iter.next();
            String value = map.get(key);

            System.out.println("key="+key+",value="+value);
        }
    }
}

(2) 旧的子类:Hashtable

Hashtable简单了解一下就好,也是Map接口的一个旧的子类

package com.shxt.demo04;

import java.util.*;

public class Demo04 {
    public static void main(String[] args) {
        Map<String,String> map  = null;
        map = new Hashtable<>();
        //增加内容
        map.put("book","西游记");
        map.put("name","吴承恩");
        map.put("type","小说");

        Set<String> keys = map.keySet();//set集合中存储的key
        Iterator<String> iter = keys.iterator();
        while (iter.hasNext()){
            String key = iter.next();
            String value = map.get(key);

            System.out.println("key="+key+",value="+value);
        }
    }
}

HashMap 与 Hashtable 的比较

编号比较点HashMapHashtable
1 性能 采用异步处理方式,性能高 采用同步处理方式,性能较低
2 线程安全 属于非线程安全的操作 属于线程安全的操作类
3 空键 允许将key设置为null 不允许key设置为null,否则会出现NullPointerException异常

(3) 排序的子类:TreeMap

package com.shxt.demo04;

import java.util.*;

public class Demo05 {
    public static void main(String[] args) {
        Map<String,String> map  = null;
        map = new TreeMap<>();
        //增加内容
        map.put("D","西游记");
        map.put("C","吴承恩");
        map.put("Z","小说");

        Set<String> keys = map.keySet();//set集合中存储的key
        Iterator<String> iter = keys.iterator();
        while (iter.hasNext()){
            String key = iter.next();
            String value = map.get(key);

            System.out.println("key="+key+",value="+value);
        }
    }
}

有点长,如果有需要对javaSE集合类感兴趣的话可以加群 642830685 找管理员免费领取一份JavaSE集合精讲视频。欢迎所有学习java的朋友加群交流学习!