一. 集合的概述
1. 什么是集合?有什么用?
数组其实就是一个集合。集合实际上就是一个容器。可以来容纳其它类型的数据。
集合为什么说在开发中使用较多?
集合是一个容器,是一个载体,可以一次容纳多个对象。在实际开发中,假设连接数据库,数据库当中有10条记录,那么假设把这10条记录查询出来,在java程序中会将10条数据封装成10个java对象,然后将10个java对象放到某一个集合当中,将集合传到前端,然后遍历集合,将一个数据一个数据展出来。
2. 集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址。(或者说集合中存储的是引用。)
list.add(100) ; // 自动装箱Integer
注意:
集合在java中本身是一个容器,是一个对象。
集合中任何时候存储的都是 “引用”。
3. 集合内存图示

4. 在Java中每一个不同的集合,底层都会对应不同的数据结构
往不同的集合中存储元素,等于将数据放到了不同的数据结构当中。
什么是数据结构?
数据存储的结构就是数据结构。
不同的数据结构,数据存储方式不同
例如:
New ArrayList (); 创建一个集合,底层是数组。
New LinkedList ();创建一个集合对象,底层是链表。
New TreeSet (); 创建一个集合对象,底层是二叉树。
…
5. 集合在JDK的哪个包下?
在java.util.*包下;
所有的集合类和集合接口都在 java.util 包下。
6. 在Java中集合分为两大类
一类是单个方式存储元素:
单个方式存储元素,这一类集合中超级父接口:
java.util.Collection;
一类是以键值对的方式存储元素:
以键值对的方式存储元素,这一类集合中超级父接口:
java.util.Map;
二. 集合的继承结构图

list的实现类

set的实现类:

三. Map集合继承结构图

四. 所有实现类总结
■ ArrayList: 底层是数组。
■ LinkedList: 底层是双向链表。
■ Vector: 底层是数组,线程安全的,效率较低,使用较少。
■ HashSet: 底层是 HashMap,放到 HashSet 集合中的元素等同于放到 HashMap 集合 key 部分了。
■ TreeSet: 底层是 TreeMap, 放到 TreeSet 集合中的元素等同于放到 TreeMap 集合 key 部分了。
■ HashMap: 底层是哈希表。线程不安全。
■ Hashtable: 底层也是哈希表,只不过线程安全的,效率较低,使用较少。
■ Properties: 是线程安全的,并且 key 和 value 只能存储字符串 String。
■ TreeMap: 底层是二叉树。TreeMap 集合的 key 可以自动按照大小顺序排序。
1. List集合存储元素的特点:
- 有序可重复。
- 有序:存进去的顺序和取出的顺序相同,每一个元素都有下标。
- 可重复:存进去1,可以再存储一个1。
2. Set集合存储元素的特点:
- 无序不可重复
- 无序:存进去的顺序和取出的顺序不一-定相同。 另外Set集合中元素没有下标。
- 不可重复:存进去1,不能再存储1了。
3. SortedSet (SortedMap) 集合存储元素特点:
- 首先是无序不可重复的,但是 SortedSet 集合中的元素是可排序的。
- 无序:存进去的顺序和取出的顺序不一定相同。另外 Set 集合中元素没有下标。
- 不可重复:存进去 1, 不能再存储 1 了。
- 可排序:可以按照大小顺序排列。
Map 集合的 key,就是一个 set 集合。 往 set 集合中放数据,实际上到了 Map 集合的 key 部分。
五. Collection中能存放什么元素
没有使用“ 泛型 ”之前,Collection中可以存储Object的所有子类型。
使用了“泛型”之后,Collection中只能存储某个具体的类型。
Collection中什么都可以存,只要是Object的子类型就可以。(集合中不能直接存储基本数据类型,也不能存储java对象,只是存储java对象的内存地址。)
六. Collection中的常用方法
1. 向集合中添加元素:boolean add(Object e)
package com.company;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionText {
public static void main(String[] args) {
//创建一个集合对象
//Collection c =new Collection() ;//接口是抽象的,无法实例化
//多态
Collection c = new ArrayList();
//测试add方法
c.add(1200);//自动装箱,实际上是放进去了一个对象的内存地址。
//Integer x = new Integer(1200);
c.add(3.14);//自动装箱,存的是地址
c.add(new Object());
c.add(new Student());
c.add(true);//自动装箱
System.out.println(c);
}
}
class Student{
}

2. 获取集合中元素的个数:int size()
在上面代码下加入改行代码:
System.out.println("集合中元素的个数" + c.size());

3. 清空集合:void clear()
加入此代码:
c.clear();
System.out.println("集合中元素的个数" + c.size());
运行结果为:

4. 判断当前集合是否含有某元素:boolean contains(Object o)
c.add("hello");
c.add("world");
c.add("浩克");
c.add("绿巨人");
boolean flag = c.contains("绿巨人");//含有则为true,不包含则为false
System.out.println(flag);

5. 删除集合中的某个元素:boolean remove(Object o)
c.remove("浩克");
System.out.println("集合中元素的个数" + c.size());

6. 判断集合是否为空:boolean isEmpty()
System.out.println(c.isEmpty());
//清空
c.clear();
System.out.println(c.isEmpty());
运行结果:

7. 把集合转换成数组:Object[ ] toArray()
c.add("abc");
c.add("def");
c.add(100);
c.add("helloworld");
//转换成数组
Object[] objs = c.toArray();
for (int i = 0 ; i < objs.length ; i++){
System.out.println(objs[i]);
}
System.out.println(Arrays.toString(objs));
运行结果:

七. Collection集合遍历/迭代
迭代器是一个对象
有三个方法:
- Boolean hasNext () 如果仍有元素可以迭代,返回 true
- Object next () 返回迭代的下一个元素
- Void remove () 从迭代器指向的 Collection 中移除迭代器返回的最后一个元素(可选操作)
对集合 Collection 进行遍历/迭代
- 第一步:获取集合对象的迭代器对象 Iterator
- 第二步:通过以上获取的迭代器对象开始迭代/遍历集合
以下两个方法是迭代器对象 Iterator 中的方法:- Boolean hasNext () 如果仍有元素可以迭代,返回 true。
- Object next () 返回迭代的下一个元素

package com.company.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionText {
public static void main(String[] args) {
//注意:遍历/迭代方式,是所有Collection通用的一种方式
//在Map集合中不能用,在所有的Collection以及子类中使用
//创建集合对象
Collection c = new ArrayList();//后面的集合无所谓,主要是看前面的Collection接口,怎么迭代/遍历
//添加元素
c.add("abc");
c.add("def");
c.add(100);
c.add(new Object());
//对集合Collection进行遍历/迭代
//第一步:获取集合对象的迭代器对象Iterator
Iterator it = c.iterator();
//第二步:通过以上获取的迭代器对象开始迭代/遍历集合
/*以下两个方法是迭代器对象Iterator中的方法:
boolean hasNext()如果仍有元素可以迭代,返回true。
Object next() 返回迭代的下一个元素
*/
while (it.hasNext()){
//不管当初存进去什么,取出来统一都是Obj。
Object obj = it.next();
System.out.println(obj);
}
/*
hasNext = it.hasNext();
System.out.println(hasNext);
if (hasNext){
Object obj = it.next();
System.out.println(obj);
}
hasNext = it.hasNext();
System.out.println(hasNext);
if (hasNext){
Object obj = it.next();
System.out.println(obj);
}
hasNext = it.hasNext();
System.out.println(hasNext);
if (hasNext){
Object obj = it.next();
System.out.println(obj);
}
hasNext = it.hasNext();
System.out.println(hasNext);
if (hasNext){
Object obj = it.next();
System.out.println(obj);
}*/
}
}
未注释前:

注释后:

八. Set接口
Set集合存储元素的特点:无序不可重复
- 无序表示存进去是这个顺序,取出来就不一定是这个顺序了。
- Set集合中的元素还不能重复。
另外Set集合没有下标。
九. HashSet集合
储存元素的特点:无序不可重复
import java.util.HashSet;
import java.util.Set;
public class HashSetText {
public static void main(String[] args) {
Set<String> strs = new HashSet<>();
strs.add("hello3");
strs.add("hello4");
strs.add("hello1");
strs.add("hello2");
strs.add("hello3");
strs.add("hello3");
for (String s : strs){
System.out.println(s);
}
}
}
运行结果:

结论:
1、存储时顺序和取出的顺序不同
2、不可重复
3、放到HashSet集合中的元素实际上是放到HashMap集合的key部分了
十. TreeSet集合
储存元素的特点:无序不可重复,但是存储的元素可以自动按照大小顺序自动排序,称为可排序集合。
这里的无序指的是存进去的顺序和取出来的顺序不同。并且没有下标。
TreeSet 底层实际上是一个 TreeMap,放到 TreeSet 集合中的元素,等同于放到 TreeMap 集合的 key 部分了
TreeSet 对 String 是可排序的(按照字典顺序):
import java.util.Set;
import java.util.TreeSet;
public class TreeSetText {
public static void main(String[] args) {
Set<String> s = new TreeSet<>();
s.add("a");
s.add("b");
s.add("z");
s.add("y");
s.add("z");
s.add("k");
s.add("m");
for (String str : s){
System.out.println(str);
}
}
}
运行结果:

Tree无法对自定义类型排序,因为没有指定的对自定义对象之间的比较规则。即没有实现 java.lang.Comparable 接口
十一. 遗留类
1. Hashtable类
Hashtable类与HashMap类的作用一样,实际上,它们拥有相同的接口。与Vector类的方法一样。Hashtable的方法也是同步的。如果对于同步性或遗留代码的兼容性没有任何要求,就应该使用HashMap。
2. 枚举
遗留集合使用Enumeration接口对元素序列进行遍历,与 Iterator接口类似。
3. 属性映射表
属性映射表(property map)是一个类型非常特殊的映射表结构。它有下面 3 个特性:
键与值都是字符串。
表可以保存到一个文件中,也可以从文件中加载。
使用一个默认的辅助表。
实现属性映射表的 Java 平台类称为 Properties。
属性映射表通常用于程序的特殊配置选项。
4. 栈
从1.0开始,标准类库中就包含了Stack类,其中包含push方法和pop方法。但是Stack类扩展为 Vector类,从理论角度看,Vector类并不太令人满意,它可以让栈使用不属于栈的insert和remove方法。
5. 位集
Java 平台的 BitSet 类用于存放一个位序列。如果需要高效地存放位序列就可以使用位集。由于位集将位包装在字节里,所以,使用位集要比使用 Boolean 对象的 ArrayList 更加高效。



