Java集合(一)

不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。


一、引入集合框架

    回忆一下Java能够储存数据的类型。字符串:可以存储一堆字符,但是它的限制太多了,数据不便于储存;数组:可以存储相同类型的数据,这倒是比字符串多了一些权限,只有是类型相同的数据,无论是对象还是基本数据类型,都可以存储。那么又有一个问题了,如果一个场景,当前不知道要存储多少数据,多少个对象,这使用数组就很麻烦了,我们都知道数组一旦定义下来,那么它的长度就固定了,虽然可以拷贝数组,这代码量和性能就不可控了。那么这时候一个框架出现了,那么就是集合(或叫容器)。集合和数组最大的特点就是它的长度是可变的,由此就可以解决刚才的场景了,那么接下来就来学习一下集合是个什么东西。

二、集合家族体系

    集合是在java.util库下的,它有两大阵营,Collection和Map。Collection是单列的,Map是双列的,简单的说就是Collection里的实现是由一个独立元素组成的序列;Map是由键值对组成,使用键来找值。下图是集合结果图:
在这里插入图片描述

以上就是集合类的结构图,有些实现类没有列举出来,但是以上的都是比较常用的,经典的实现类。
如果把上面的实现类掌握了,那么这个集合框架就掌握的差不多了。

三、集合顶级接口 — Collection

1、简介

    由上图可知,结合的顶级接口是Collection,到这里你可以会有疑惑,前面明显还有一个Iterator,这个是集合遍历使用的,叫迭代器。因此集合的顶级父类是Collection,而实现了这个接口的类,就是单列的集合。我们又可以知道Collection下面有三个子接口,分别是:List、Set、Queue,这三个接口才是区分单列集合的各有所长之处。List必须按照元素插入顺序来保存;Set中不能存在重复元素;而Queue则要按照排队规则来输出元素(通常与元素被插入的顺序一样)。
    Map是集合另一个阵营的(这里有很多人会混为Map继承了Collection),它在某种意义上将数值与对象关联在一起了。 就是使用另一个对象查找某一个对象,所以它也被称为关联数组,或者称字典。 因为它使用一个键对象来查询一个值对象,就像我们在字典中使用一个单词来查其定义一样。Map是非常强大的编程工具。

2、Collection接口常用方法

    这个接口的方法有很多,不过我们不需要把全部方法都记忆,我们把几个常用的,重点关注就行了。看API之前,我们先思考一下一个容器,最基本的操作是什么呢?把一个对象放进去、取出来、该对象是否存在容器?这些是我们猜想的,下面我们来看看常用的API:

方法描述
int size()获取当前集合的大小
boolean add(E e)给该集合添加指定对象
boolean remove(Object o)在该集合中查找对象o,存在则删除
void clear()清空该集合元素
boolean isEmpty()判断当前集合是否为空
boolean contains(Object o)判断o对象是否在该集合中
Iterator iterator()迭代器,该迭代器对象默认指向当前集合的0索引。集合遍历专属
boolean addAll(Collection<? extends E> c)集合合并
Object[] toArray()把集合中的元素存储到数组中

我们刚刚猜想的方法还是有的,添加操作(add)、删除操作(remove)、判断该对象是否存在(contanins)。接下来就开始正题了,除了以上的通用方法外,List、Set、Queue它们各有什么独特方法呢,我们拭目以待。

四、List系列

1、特点

    List系列的集合的特点是:有序列、可重复、有索引,其下面典型的实现类分别是ArrayList和LinkedList,这里我们也只讲解这两个类。
    首先是它们的底层实现以及特点:

	ArrayList:基于数组实现的,默认长度为10;特点是根据索引查询速度快,增删操作相对慢。
	LinkedList:基于双链表实现;特点是查询效率低,增删首尾元素效率高,线程不安全。

2、ArrayList详解

    现在我们已经知道了ArrayList是基于数组实现的,数组我们已经很熟悉了,那么它的底层真的有数组的身影?我们不妨进入源码查看一番。

public class ArrayList<E> implements List<E>{
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    transient Object[] elementData; 
    }

 public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    

以上是ArrayList的源码,我们来看看无参构造,当我们用关键字new的时候,它就创建了一个空的数组,不过这种创建方式和我们平时创建的有些不一样,不过我们的目的是看是否使用了数组,后面的我们暂时不用深入了解。

    接下来是特点,刚刚我们讨论到ArrayList查询速度快,快的元素是它可以根据索引来查询,那么我们应该想到这个类应该有很多关于索引的方法了。关于索引比较常用的方法如下表:

方法描述
void add(int index, E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

3、LinkedList详解

    我们需要先知道什么是双链表。我们先看图:
在这里插入图片描述
双链表上的每个结点都有 4个值,l-Nnext 指针表示它左边的结点的下标,r-Nnext 指针表示它右边的结点的下标,其他的数组和变量和单链表的存储代表一个意思。这也就是说,首尾操作对于LinkedList来说的很简单的,那么它的独特方法就出来了,我们来看看操作首尾的方法:

方法描述
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素

案例:模拟栈与队列
首先我们得清楚栈与队列的出入顺序,栈:先进后出,后进先出原则;队列:先进先出,后进后出原则。知道了这个规则,我们就来使用LinkedList模拟一下吧:

 public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        //模拟栈 先进后出
        System.out.println("进栈/压栈");
        list.addFirst("java");
        list.addFirst("mysql");
        list.addFirst("spring");
        list.addFirst("python");
        list.addFirst("vue");
        System.out.println("全部进入完毕,出栈/弹栈:");
        System.out.println(list.getFirst());
        list.removeFirst();
        System.out.println(list);

        System.out.println(list.getFirst());
        list.removeFirst();
        System.out.println(list);

		System.out.println(list.getFirst());
        list.removeFirst();
        System.out.println(list);

        list.removeFirst();
        System.out.println(list);
        System.out.println(list.getFirst());

        list.removeFirst();
        System.out.println(list);

		//队列:先进先出
        System.out.println("开始归队");
        list.addLast("java");
        list.addLast("mysql");
        list.addLast("spring");
        list.addLast("python");
        list.addLast("vue");
        System.out.println("全部归队完毕,开始出列:");
        System.out.println(list.getFirst());
        list.removeFirst();
        System.out.println(list);

        System.out.println(list.getFirst());
        list.removeFirst();
        System.out.println(list);

        System.out.println(list.getFirst());
        list.removeFirst();
        System.out.println(list);

        list.removeFirst();
        System.out.println(list);
        System.out.println(list.getFirst());

        list.removeFirst();
        System.out.println(list);
    }

执行结果图:
在这里插入图片描述

在这里插入图片描述

细心的你也许发现了一个问,上面的例子为啥不使用循环呢,因为使用for循环如果不小心的话会出现问题,您实一下就清楚了。如果想使用循环的话,可以参照以下代码:

LinkedList<String> list = new LinkedList<>();
        //模拟栈 先进后出
        System.out.println("进栈/压栈");
        list.push("java");
        list.push("mysql");
        list.push("spring");
        list.push("python");
        list.push("vue");
        System.out.println("全部进入完毕,出栈/弹栈:" +list.size());
        for (int i = 0; i <list.size()+5 ; i++) {  //条件也可以写成:i < 5
            System.out.println(list.getFirst());
            System.out.println(list);
            list.removeFirst();
        }

执行结果是一样的。


五、小结

本章简单的介绍了Java集合框架的家族体系,简单的说就是被Collection和Map两个接口继承的实现类,即为集合类库。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
掌握集合的概念、体系结构、分类及使用场景 2)了解Set接口及主要实现类(HashSet、TreeSet) 3)了解List接口及主要实现类(ArrayList、LinkedList、Vector) 4)了解Map接口及主要实现类(HashMap、TreeMap、HashTable) 二、实验内容及步骤 1、编写程序练习将以下5个Person类的对象放在一个HashSet中。 姓名:张三 身份证号:178880001 姓名:王五 身份证号:178880002 姓名:李四 身份证号:178880003 姓名:王五 身份证号:178880002 姓名:李四 身份证号:178880004 注意:因为Person类是自定义类,需要重写hashCode()方法和equals()方法,并规定只有姓名和身份证号都相等,则对象相等。 其中计算哈希码的算法:(31 + ((name == null) ? 0 : name.hashCode()))*31 + id (注:name:Person对象的姓名,id:Person对象的身份证号) 主方法中作如下测试: 1)创建一个可放置Person类对象的HashSet; 2)依次添加上述5个对象到HashSet中; 3)把集合中的元素打印出来(使用迭代器Iterator) 2、编写程序练习List集合的基本使用: 1) 创建一个只能容纳String对象名为names的ArrayList集合; 2)按顺序往集合中添加5个字符串对象:"张三"、"李四"、"王五"、"马六"、"赵七"; 3)对集合进行遍历,分别打印集合中的每个元素的位置与内容; 4)打印集合的大小,然后删除集合中的第3个元素,并显示删除元素的内容,然后再打印目前集合中第3个元素的内容,并再次打印集合的大小。 3、编写程序练习Map集合的基本使用: 1)创建一个只能容纳String对象的person的HashMap集合; 2)往集合中添加5个"键-值"对象: "id"-"1"; "name"-"张三"; "sex"-"男"; "age"-"25"; "hobby"-"爱学Java" 3)对集合进行遍历,分别打印集合中的每个元素的键与值; 4)打印集合的大小,然后删除集合中的键为age的元素,并显示删除元素的内容,并再次打印集合的大小。 四、思考题 1、集合中的List、Set、Map有哪些不同? 2、为什么使用集合框架,而尽可能少用数组作为存储结构? 3、如何使用TreeSet实现第一题?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值