Collection集合总结

Collection接口继承体系图

 Collection接口常用方法

返回值类型方法    解释
booleanadd(E e)向列表的尾部添加指定的元素(可选操作)
booleanaddAll(Collection<? extends E> c)将指定 collection 中的所有元素都添加到此 collection 中(可选操作)
voidclear()移除此 collection 中的所有元素(可选操作)
booleancontains(Object o)判断集合是否包含此元素,包含返回true
booleanequals(Object o)比较此 collection 与指定对象是否相等
inthashCode()返回此 collection 的哈希码值
booleanisEmpty()如果此 collection 不包含元素,则返回 true
Iterator<E> iterator()返回在此 collection 的元素上进行迭代的迭代器
booleanremove(Object o)删除第一次出现在集合的指定元素,返回值为被删除的元素(如果存在)
intsize()返回列表中的元素数
Object[]toArray()返回按适当顺序包含列表中的所有元素的数组(不常用)

一、List集合

List 就是列表的意思,它是Collection 的一种,即继承了 Collection 接口,以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置(索引)的操作。List 是按对象的进入顺序进行保存对象,而不做排序或编辑操作。它除了拥有Collection接口的所有的方法外还拥有一些其他的方法。
面向位置(索引)的操作包括插入某个元素或 Collection 的功能,还包括获取、除去或更改元素的功能。在 List 中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置。

List接口子实现类的特点

  • ArrayList:底层结构是数组,增删慢,查询快(线程不安全,效率高)
  • Vector:底层结构是数组,增删,查询都很慢(线程安全,因此查询效率比ArrayList要低)
  • LinkedList:内部是链表数据结构,,增删元素的速度很快(线程不安全)

List集合特有的常用方法

返回值类型方法    解释
booleanaddAll(Collection<? extends E> c)按照迭代器返回的元素顺序,将指定集合插入到指定集合中
booleanaddAll(int index, Collection<? extends E> c)从指定的位置开始,将指定 collection 中的所有元素插入到此列表中
Eget(int index)返回列表中指定位置的元素
intindexOf(Object o)返回该元素第一次出现在集合中的索引值;若不包含该元素,则返回 -1
intlastIndexOf(Object o)返回该元素最后一次出现在集合中的索引值;若不包含该元素,则返回 -1
ListIterator<E>listIterator()返回此列表元素的列表迭代器(按适当顺序)
Eremove(int index)根据索引删除元素,返回值为被删除的元素
Eset(int index, E element) 根据索引,修改集合中的元素,返回值为替换前的元素

常用方法演示

    public void test01() {
        ArrayList<String> list = new ArrayList<>();
        list.add("三国演义");
        list.add("西游记");
        list.add("水浒传");
        list.add("红楼梦");
        Iterator<String> ite = list.iterator();
        while (ite.hasNext()) {
            String next = ite.next();
            // 判断当前元素是否是"西游记"
            if (next.equals("西游记")) {
                // 根据索引修改当前元素为 "吴承恩"
                list.set(list.indexOf(next), "吴承恩");
            }
            // 输出结果:三国演义	西游记	水浒传	红楼梦
            System.out.print(next + "\t");
        }
        System.out.println();
        // 将集合list转换成Object数组
        Object[] arr = list.toArray();
        for (int i = 0; i < arr.length; i++) {
            String str = (String) arr[i];
            // 输出结果:三国演义	吴承恩	水浒传	红楼梦
            System.out.print(str + "\t");
        }
    }

注意:集合中的元素必须是对象,不能是基本数据类型(JDK 1.5后提供自动拆装箱)

Collection集合的remove(obj)方法和Iterator接口中的remove()方法的使用

    public void test02() {
        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        list1.add("三国演义");
        list1.add("西游记");
        list1.add("水浒传");
        list1.add("红楼梦");
        Iterator<String> ite = list1.iterator();
        while (ite.hasNext()) {
            String next = ite.next();
            // 判断当前元素是否是"西游记"
            if (next.equals("西游记")) {
                // 移除当前元素"西游记"
                //list.remove(next); //报错,并发修改异常ConcurrentModificationException
                // 使用Iterator的方法移除元素不会报错
                ite.remove();
            }
        }
        list2.addAll(list1);
        System.out.println("list1 = " + list1);// list1 = [三国演义, 水浒传, 红楼梦]
        System.out.println("list2 = " + list2);// list2 = [三国演义, 水浒传, 红楼梦]
    }

注意:迭代器遍历集合时,使用Collection集合的remove(obj)方法会报并发修改异常java.util.ConcurrentModificationException,

但使用Iterator接口中的remove()方法,程序运行正常。

出现异常 java.util.ConcurrentModificationException的原因及解决办法?

原因:在迭代过程中,使用了List集合的方法对元素进行操作。导致迭代器并不知道集合中的变化,容易引发数据的不确定性

解决办法:

  • 在迭代时,不要使用集合的方法操作元素
  • 使用普通的for循环遍历集合
  • 使用ListIterator迭代器操作元素,解决了使用Iterator迭代过程中可能会发生的错误情况(后面会讲)

1.1、ArrayList集合特点及方法

特点:数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。

常用方法:全部继承自List接口

1.2、LinkedList集合的特点及方法

特点:数据存储的结构是链表结构。元素增删快,查找慢。实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法

常用方法:

返回值类型方法    解释
voidaddFirst(E e)将指定元素插入此列表的开头
voidaddLast(E e)将指定元素添加到此列表的结尾 
EgetFirst() 返回此列表的第一个元素(链表为空,抛出NoSuchElementException)
EgetLast()返回此列表的最后一个元素
EremoveFirst()移除并返回此列表的第一个元素
EremoveLast()移除并返回此列表的最后一个元素
EpeekFirst()获取但不移除此列表的第一个元素(链表为空,返回null)
EpollFirst()获取但不移除此列表的第一个元素(列表为空,返回 null)

利用LinkedList集合特点模拟一个堆栈或者队列数据结构

堆栈:先进后出 First In Last Out

队列:先进先出 First In First Out

   /**
     * 利用LinkedList集合特点模拟一个堆栈
     * 堆栈:先进后出 First In Last Out
     */
    @Test
    public void test05() {
        LinkedList<String> lklist = new LinkedList<>();
        lklist.addLast("one");
        lklist.addLast("two");
        lklist.addLast("three");
        lklist.addLast("four");
        lklist.addLast("five");
        Iterator<String> ite = lklist.iterator();
        while (ite.hasNext()) {
            String next = ite.next();
            System.out.print(next + " ");// one two three four five
        }
    }

    /**
     * 利用LinkedList集合特点模拟队列数据结构
     * 队列:先进先出 First In First Out
     */
    @Test
    public void test06() {
        LinkedList<String> lklist = new LinkedList<>();
        lklist.addFirst("one");
        lklist.addFirst("two");
        lklist.addFirst("three");
        lklist.addFirst("four");
        lklist.addFirst("five");
        Iterator<String> ite = lklist.iterator();
        while (ite.hasNext()) {
            String next = ite.next();
            System.out.print(next + " "); // five four three two one
        }
    }

1.3、Vector集合的特点及方法(被ArrayList取代)

特点:数据存储的结构是数组结构,为JDK中最早提供的集合。Vector集合已被ArrayList替代。枚举Enumeration已被迭代器Iterator替代。

常用方法:

返回值类型方法    解释
voidaddElement(E obj)将指定的组件添加到此向量的末尾,将其大小增加 1
EelementAt(int index) 返回指定索引处的组件
Enumeration<E>elements()返回此向量的组件的枚举

Vector集合对ArrayList集合使用的对比

二、Set接口

Java 中的Set和正好和数学上直观的集(set)的概念是相同的。Set最大的特性就是不允许在其中存放的元素是重复的。根据这个特点,我们就可以使用Set 这个接口来实现前面提到的关于商品种类的存储需求。Set 可以被用来过滤在其他集合中存放的元素,从而得到一个没有包含重复新的集合。

Set接口中的方法和Collection一致,这里就不列出了

Set接口子实现类的特点

  • HashSet:内部数据结构是哈希表(线程不安全)
  • LinkHashSet:内部数据结构是链表和哈希表(线程不安全)
  • TreeSet:内部数据结构是平衡树(Balanced tree),元素唯一、有序(线程不安全)

重写hashCode()、equals()方法,保证Set集合元素唯一性,源码判断步骤如下

①判断的是两个元素的哈希值是否相同,即hashCode()

如果哈希值不同,不需要判断equals(),就可以保证元素的唯一了

如果相同,再判断两个对象的内容是否相同,即equals()

注意:hashCode()方法判断对象的哈希值是否相同;equals()方法判断内容是否相同

注意:HashSet存储JavaAPI中提供的类型元素时,不需要重写元素的hashCode()和equals()方法,因为这两个方法,在JavaAPI的每个类中已经重写,如String类、Integer类等,但是自定义类需要自己重写hashCode()和equals()方法,否则无法保证元素唯一性。

下面代码体现了Set集合的唯一性

    /**
     * 利用Set集合元素唯一性移除List集合中重复元素
     * String类已经重写hashCode()和equals()方法
     */
    @Test
    public void test03() {
        Collection<String> set = new HashSet<>();
        Collection<String> list = new ArrayList<>();
        for (int i = 5; i > 0; i--) {
            list.add(i + "");
        }
        list.add("1");
        list.add("3");
        list.add("5");
        System.out.println("list = " + list);// 输出结果:list = [5, 4, 3, 2, 1, 1, 3, 5]
        set.addAll(list);
        System.out.println("set = " + set);// 输出结果:set = [1, 2, 3, 4, 5]
    }

疑惑:set = [1, 2, 3, 4, 5]的输出结果有点疑惑,set集合自动将结果排序了,查看了下Integer类实现了Comparable接口

2.1、HashSet的特点及方法

特点:数据存储的结构是哈希表。元素存取无序,集合元素唯一,元素并不是按照存入时的顺序(和List显然不同) 是按照哈希值确定存放在HashSet集合的位置,因此也是按照哈希值取数据的

常用方法:全部实现自Set接口

2.2、LinkHashSet的特点及方法

特点:链表和哈希表组合的一个数据存储结构,因此元素存取有序、且保证元素唯一性

常用方法:全部实现自Set接口

    public void test07() {
        Set<String> set = new LinkedHashSet<String>();
        set.add("三国演义");
        set.add("西游记");
        set.add("水浒传");
        set.add("红楼梦");
        set.add("西游记");
        set.add("三国演义");
        Iterator it = set.iterator();
        while (it.hasNext()) {
            System.out.print(it.next() + "\t");// 三国演义  西游记  水浒传  红楼梦
        }

    }

2.3、TreeSet的特点及方法

特点:TreeSet集合的底层是二叉树进行排序的,集合元素唯一性

常用方法:

TreeSet判断元素唯一性的方式:根据比较方法的返回结果判断,是0,就是相同元素;不是0,元素不相同

TreeSet对元素进行排序的方式

  • 元素自身具备比较性:元素实现Comparable接口,重写compareTo方法
  • 容器具备比较性:使用带参构造创建TreeSet(Collection<? extends E> c) ,实现compare(T o1, T o2)方法

注意:当Comparable比较方式和Comparator比较方式同时存在时,以Comparator的比较方式为主。

   /**
     * 验证TreeSet集合的唯一、排序
     */

    @Test
    public void test08() {
        TreeSet<String> ts = new TreeSet<>();
        ts.add("5");
        ts.add("2");
        ts.add("3");
        ts.add("4");
        ts.add("1");
        ts.add("5");
        Iterator<String> ite = ts.iterator();
        while (ite.hasNext()) {
            Object next = ite.next();
            System.out.print(next + " ");// 输出结果:1 2 3 4 5
        }
    }

三、总结(集合框架中常用类比较)

看到array,就要想到角标

看到link,就要想到first,last

看到hash,就要想到hashCode,equals

看到tree,就要想到两个接口Comparable,Comparator

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值