集合框架:List、Set、Map

175 阅读7分钟

集合框架

复习

  1. 包装类

作用:是在基本数据类型和引用数据类型之间搭建“桥梁”。

熟练掌握 --- 每种基本数据类型对应的包装类到底是谁。String与各种基本数据类型的转换。

理论掌握 --- 当出现“自动封箱”或“自动拆箱”的语法时,要知道这是语法糖。

```
Object o = 10;
```

2. 时间日期

Date 和 三个Local、以及DateTimeFormatter必须掌握。

API:

三个Local的now(),of(),plus(),minus(),以及格式化的用法。

  1. Properties属性文件

其实是我们目前没有学习持久化技术,于是选择了一种“代码最简单”的替代方式。

集合框架综述

集合 --- 把批量数据集中合并在一起进行操作。

数组是集合的一种,而且是最简单最原始的一种。体现在三个方面:

1、只能存放同一数据类型元素;

2、大小一旦确定不能更改;

3、所有元素存放在连续内存地址空间。

之前的学习中,我们通过面向对象的多态特性,解决了问题1;我们通过面向对象的类的封装性,解决了问题2。但是,我们没有解决问题3,因为这涉及到了数据在内存中的存放形式问题(数据结构)。

但是,在JDK当中,早就写好了解决以上3个问题的集合类。而且不止一个,它们构成了我们今天要学习的Java集合框架(JCF)。

集合框架的组成

  1. Collection接口是所有集合类的根接口;
  2. List、Set、Map代表了三种结构不同使用场景不同的三种集合类型。其中:List和Set直接继承于Collection,Map间接来自于Collection;
  3. 我们在实际使用的时候,用的是List/Set/Map的实现类。需要掌握常见类的使用API。
  4. Collections和Arrays是集合框架提供的两个工具类,自带了大量对于批量数据的操作方法(包括:找最大,找最小,排序等等)
  5. 比较器(Comparator和Comparable)\ 迭代器(Iterator) 也是用于辅助操作集合内容的接口。
  6. 在集合框架的类设计中,还使用了一种叫做"泛型"的Java语法,我们也需要了解一下。

List(列表)

List的特点 - 线性(有序)

我们往List集合中放置的元素,会根据我们放的顺序对应它存的顺序。正是因为有序这个特点,List当中的元素都是有下标的,而且所有的下标都是从0开始的。

ArrayList

这个类从名字上就可以看出来,他是在底层使用数组来实现的,跟我们之前自定义的Array几乎是一摸一样的设计方案。

添加元素 --- add

注意:

添加的元素默认都是Object类型,基本数据类型进去也是用的“自动封箱”;

可以添加重复的;

可以添加null。

获取元素 --- get

根据下标去获取该位置的元素;

下标不对,会报异常。

修改元素 --- set

根据下标去修改该位置的元素;

下标不对,会报异常

删除元素 --- remove removeAll

注意:

remove是重载方法,可以根据下标删除, 也可以根据元素删除(如果有重复元素,只删除一个,且是前面的)。

遍历:

1、普通for循环照用;

2、迭代器循环;

将集合当中的元素,从头到尾访问一遍。最大的特点就是不能回头,也不会跳过。

3、for-each循环 是专用于从集合类(包括数组)当中,挨个儿每一个元素的循环语法。只要我们不考虑在遍历操作中增/删/跳的动作,只是简单的从头到尾访问,那么使用这个语法比普通for还要简单。

大家需要知道:集合框架类的for-each语句在底层中是基于迭代器(Iterator)实现的。

    //从集合对象中,每次循环取一个元素赋值给变量
    for(元素类型 变量 : 集合对象){
        //实现对变量的操作
    }

LinkedList

拥有和ArrayList一摸一样的API,甚至执行后的效果也是一样的。但是LinkedList在底层的数据结构上采用了“双向链表”的设计。

LinkedList和ArrayList的区别

1、底层区别:前者是双向链表;后者是数组;

2、效率区别:前者在执行元素的增删动作的时候效率更高;后者在执行遍历查找动作的时候效率更高。

ArrayList和Vector的区别

都是List集合,底层都是数组,区别:

ArrayList是线程不安全的;

Vector是线程安全的。

Set(集)

Set的特点:不能重复。

Set集合中相同的元素只能存放一次,并且由于线性不是它的特点,所以我们放的顺序和它存的顺序不一致,因此在Set当中是没有下标这个概念的。

HashSet

从名称上看,这个集合带有“Hash”这个标识,说明必然它会和我们之前看到的Object类当中的hashcode方法有关系。

增加元素 -- add

当我们重复添加一个已经在Set当中存在的元素时,不会报错,只是没有放进去。

允许放入null元素,当然也只能放一个。

获取元素 --- 没有获取某个元素的方法

修改元素 --- 没有修改指定元素的方法

删除元素 --- remove removeAll

remove方法没有重载,只能根据对象进行删除。

获取元素个数 -- size

遍历 :

1、不能使用普通for循环;

2、只能使用for-each语句,从头到尾访问一次。

HashSet是如何判断两个元素重复的?

HashSet是通过调用元素的hashcode方法和equals方法来判断两个元素是否重复的。在Java的规范当中要求:两个相同元素理论上应该具有同样的hashcode值,以及equals要返回true。

HashSet也是按照这个规范来做的,它会先判断元素的hashcode值是否一直,然后再调用equals方法看是否返回true。

TreeSet

Map(映射)

从名称上,我们能看出来Map这种集合,它的元素是成对存放的。它的元素是以KV对的形式存放的。Key不能重复,Value是通过Key去映射的。

HashMap

HashMap是通过hashcode值保证Key的唯一性的。

增加 --- put

Key和Value都可以为null,但是由于Key不能重复,所以只有一个Key可以为null。

获取 --- get

通过Key去获取值 如果Key不存在,不会报错,只会返回null。

修改 --- put

通过已经存在的key,去修改它的值。

删除 --- remove

通过Key进行删除,如果Key不存在,也不会报错,只是没有执行删除操作而已。

获取个数 --- size

遍历 --- 需要单独遍历所有的Key或所有的值

keySet() --- 获取所有的Key,返回一个Set集合

Values() --- 获取所有的值,返回一个Collection集合

然后我们再通过for-each循环遍历每个Key或每个值。

Properties

它也是Map下的一个实现类,只不过作为集合类型,它比较弱。因为它的key和值都是String类型,它唯一擅长的就是它除了充当容器,还可以操作一种格式特殊的文件(属性文件)。

这种特殊格式的属性文件,虽然结构简单,但是在一些不需要存放复杂数据的情况下,还是可以用用的。你们以后会在一些框架的配置文件中见到它。

泛型语法

在集合框架中的类型都设计了“泛型”的语法,用于限制该集合对象只能存放某种数据类型的元素。

List<String> l = new ArrayList<>();

注意:

1、<>里面只能写一种类型;

2、可以把泛型设计为放父类类型,这样它的所有子类都可以放入;

3、泛型只能是引用数据类型,若有这种需求,那么要书写的应该是该基本数据类型对应的“包装类类型”。