概述
- 集合在JDK java.util.* 包下
所有集合类和集合接口都在
- 集合是一个载体,一个容器,一次可以容纳多个对象
- 集合里存的是对象的内存地址
- 集合本身也是一个对象(有内存地址)
- 集合里可以存集合
- 不同的集合底层对应不同的数据结构
- 集合中不能直接存储基本数据类型,他会自动的帮你装箱
集合的理解和好处
之前保存数据都是用的数组,那么数组有不足的地方,分析如下:
数组缺点:
- 长度开始时必须指定,而且一旦指定,不能更改
- 保存的必须为同一类型的元素
- 使用数组进行增加元素的示意代码 - 比较麻烦 ```java // 写出Person数组扩容示意代码 Person[] pers = new Person[1]; // 大小是1 per[0] = new Person();
// 此时数组已满,增加新的person对象: Person[] pers2 = new Person[pers.length + 1]; for(){} // 循环将pers数组的东西拷进去 pers2[1] = new Person();
// 第二种数组拷贝的方法 使用System.arraycopy()方法 // 源数组 Integer[] integers = new Integer[5]; for (int i = 0; i < integers.length; i++){ integers[i] = i; } // 新的目标数组 Integer[] newIntegers = new Integer[10]; // 参数 1.拷贝源, 2.源的起点, 3.目标, 4.目标的起点, 5.要拷贝多长 // 新的数组中,没有被使用的元素为 null System.arraycopy(integers,0,newIntegers,0,integers.length);
<a name="OSstX"></a>## 集合概念1. 可以**动态保存**任意多个对象,使用比较方便。1. 提供了一系列方便的操作对象的方法:add(),remove(),set(),get()1. 使用集合添加,删除新元素的实例代码更加间接明了<a name="fxHas"></a>## 在java中集合分为两大类:- 一类是单个方式存储元素:- **单个方式存储元素**,这一类集合中超级父接口:java.util.**Collection**;- 一类是以**键值对儿**的方式存储元素- **以键值对的方式存储元素**,这一类集合中超级父接口:java.util.**Map**;<a name="93Kih"></a># Collection1. Collection 是集合里面的超级父接口1. Collection可以存储那些元素在没有使用泛型的情况下可以存储Object所有子类<br />使用了泛型,只能存储某个具体的类型<br /><a name="u7FEX"></a>### Collection 继承图<a name="BMsEi"></a># Collection接口和常用方法<a name="cMQCU"></a>### 1)Collection接口实现类的特点1. collection实现子类可以存放多个元素,每个元素可以是Object1. 有些Collection的实现类,可以存放重复的元素,有些不可以1. 有些Collection的实现类,有些事有序的 List, 有些不是有序的Set1. Collection接口没有直接的实现子类,是通过他的子接口Set和List来实现的。<a name="ztJOc"></a>### 2)常用方法1. **add**(元素) 添加一个元素1. **remove**(元素) 删除一个元素,返回一个boolean || **remove**(索引) 返回被删除的元素1. **contains**(元素) 查找该元素是否存在1. **size**() 获取元素个数1. **isEmpty**() 判断是否为空1. **clear**() 清空1. **addAll**(Collection对象) 添加多个元素1. **containsAll**(Collection对象) 查找多个元素1. **removeAll**(Collection对象) 删除多个元素```java// 创建一个集合Collection collection = new ArrayList();// add() 添加一个元素collection.add(1);collection.add(2);// remove()删除指定元素collection.remove(1);// contains() 查找元素是否存在boolean contains = collection.contains(2);// size() 获取元素个数int size = collection.size();// isEmpty() 判断是否为空boolean empty = collection.isEmpty();// clear() 清空集合collection.clear();// addAll() 添加多个元素Collection collection1 = new ArrayList();collection1.add(11);collection1.add(22);collection1.add(33);collection.addAll(collection1);// containsAll(Collection对象) 查找多个元素是否都存在boolean b = collection.containsAll(collection1);// removeAll(Collection对象) 删除多个元素collection.removeAll(collection);
注意
- 集合中存储的都是引用地址,往里面存入1 实则是存入 new Integer(1); 自动装箱
3)Collection接口遍历元素方式1 - itreator
基本介绍
- Iterator对象称为迭代器,主要用于遍历Collection集合中的元素
- 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,既可以返回一个迭代器。
- Itreator 仅仅用来遍历集合,Iterator本身并不存放对象。
List/Set/SortedSet特点

集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,
集合当中存储的都是java对象的内存地址。(或者说集合中存储的是引用。)
list.add(100); //自动装箱Integer
注意:
- 集合在java中本身是一个容器,是一个对象
- 集合中任何时候存储的都是“引用”
List
特点
- 有序
- 可重复
- 有下标 0开始 以1递增
List接口为Collection的子接口,也就是说Collection中有的方法,这里都有
创建集合 List l = new ArrayList(); 多态
List集合常用方法
void add(下标,元素) //在指定的位置插入元素
Object get(下标) //得到指定位置的元素
int indexOf("元素") //得到该元素第一次出现的下标
int lastIndexOf("元素") //得到该元素最后一次出现的下标
Object remove(下标) // 删除指定位置的元素
Object set(下标,元素) //修改指定下标的元素
链表
优点
随机增删元素效率较高
缺点
查询效率底
在开发中如果遇到了随机增删元素较多的业务时,建议使用LinkedList
ArrayList
- ArrayList集合初始化容量10
- 扩容为原容量1.5倍
-
Vector
Vector初始化容量是10
- 扩容为原容量的2倍
- 底层是数组
Vector底层是线程安全的
怎么得到一个线程安全的List
- Collections.synchronizedList(list)
集合的遍历/迭代器
此内容只能在Collection中使用Map集合不能使用
Iterator i = 集合.iterator(); // 拿到迭代器
迭代器常用方法
boolean hasNext()
如果返回true表示有元素可以迭代
如果返回false表示没有元素可以迭代
Object next();
让迭代器前进一位,并且拿到该元素
迭代器对象最初没有指向任何元素
遍历集合
Collection c = new ArrayList(); // 创建集合 多态
Iterator i = c.iterator(); //拿到迭代器
while(i.hasNext()){ //如果有元素返回true ,执行循环,没有则退出
System.out.println(i.next()); // 迭代
}
注意
- 当集合发生结构变化,一定要重新获取迭代器
- 在迭代元素时不能调用c.remove()方法 ,删除元素但是可以调用i.remove()方法 ,删除元素
泛型
在JDK5.0出现的新特性
List myList = new ArrayList<>(); <>钻石表达式
使用泛型后myList集合中只允许出现Animal类或者他的子类
优点
使用泛型后,集合中的数据类型更加统一
缺点
导致集合中的储存元素缺乏多样性
注意
使用泛型之后迭代器迭代的就不是Object类型了而是<> 这里面的类型
Set / Vector
- 底层是TreeMap
- TreeMap底层是二叉树
- 放到TreeSet集合中的元素 等同于放到TreeMap的key部分
- 特点
排序可以自定义
比较规则
升序 : return this.age-c.age;
降序 : return c.age - this.age;
例如
TreeSet<B> treeSet2 = new TreeSet<>(new Comparator<B>() {
@Override
public int compare(B b, B t1) {
return b.age - t1.age;
} //匿名内部类
});
treeSet2.add(new B(520));
treeSet2.add(new B(500));
treeSet2.add(new B(510));
treeSet2.add(new B(400));
treeSet2.add(new B(300));
for ( B b : treeSet2){
System.out.println(b);
}
结论
- 放到TreeSet或者TreeMap集合中key部分想要排序包括两种方式
- 集合中的元素类中实现Comparable接口
- 在构造的时候传一个比较器Comparator接口(对象)
- 如果比较规则不变使用Comparable接口
- 如果比较规则有多个,需要切换,用Comparator接口(匿名内部类)
Vector 集合
- 底层是数组
- 初始容量为10
- 扩容之后是原容量的2倍 10—>20—>40
- 所有的方法都是线程同步的(所以不常用)
Map
概念
Map集合以key和value的方式储存数据(键值对)
- key和value是引用数据类型
- key和value保存的是对象的内存地址
-
Map集合常用方法
put(k,v) //向Map集合中添加键值对
- get(Object key) // 通过key找到value
- void clear() //清空集合
- boolean containsKey(Object key) // 判断集合里有没有key(只在key中找)
- boolean contiansValue(Object value) //判断集合中有没有value(只在value中找)
- boolean isEmpty() //判断集合是否为空
- int size() //获取键值对的数量,一组为一个
- remove (Object key) // 通过key来删除键值对
- Collection values() // 得到所有的value元素 用一个Collection 集合接收
- Set keySet() //得到所有的key元素 用Set集合接收
哈希表数据结构(散列表)
- 哈希表是数组和单向链表的结合体
- 哈希表就是将传进来的key元素,通过hashCode算出来一个下标,将key存进去
- 如果重写hashCode方法返回都是一样的值,那么就变成了纯链表
- 如果重写的hashCode方法返回的值都不一样,那么就变成了纯数组
- 如果put(k重复了,value会覆盖)
重点
- 放在HashMap/HashSet集合里key部分的元素必须同时重写HashCode()和equals()
- hashCode()和equals()方法不需要自己写直接idea生成
- HashMap集合初始化容量必须是2的次幂,这也是官方推荐 【推荐16】
Map 继承图
HashMap
- HashMap集合的默认初始化容量为16,默认加载因子为0.75
- 默认加载因子是指HashMap集合底层数组的容量达到75%以后开始扩容
Properties
继承Hashtable
key和value都只能存String
属性类对象(线程安全)
setProperty(k,v) //存元素
getProperty(k); //通过key得到value
自平衡二叉树
遍历
前序遍历 根左右
中序遍历 左根右
后序遍历 左右根
Map集合遍历
通过获取所有的key,通过遍历key,来遍历value
Map<Integer,String>map = new HashMap<>(); map.put(1,"张三"); map.put(2,"李四"); map.put(3,"王五"); Set set = map.keySet(); // 得到所有的key元素 Iterator it = set.iterator(); //拿到迭代器 while(it.hasNext()) { Integer i = (Integer) it.next(); // 得到迭代的key String i1 = map.get(i); //通过得到迭代的key 得到value System.out.println(i); System.out.println(i1); }增强for
Map<Integer,String>map = new HashMap<>(); map.put(1,"张三"); map.put(2,"李四"); map.put(3,"王五"); Set<Integer> set = map.keySet(); // 得到所有的key元素 for(Integer i : set){ System.out.println(i+"="+map.get(i)); }大数据量时使用
Set<Map.Entry<Integer,String>> set1 = map.entrySet(); for (Map.Entry<Integer,String> node :set1){ System.out.println(node.getKey()+"="+node.getValue()); }Map总结
ArrayList 底层是数组
- LinkedList 底层双向链表
- Vector 底层是数组,线程安全 效率底,使用较少
- HashSet 底层是HashMap,放在HashSet集合中的元素,相当于放在HashMap的key部分
- TreeSet 底层是TreeMap,放到TreeSet集合里的元素等同于放在TreeMap集合中的key部分
- HashMap 底层是哈希表
- Hashtable 底层是哈希表,线程安全,效率低,使用少
- Properties 线程安全 并且key和value中只能存储字符串 String
- TreeMap 底层是二叉树,TreeMap集合中的key可以自动按照从小到大的顺序排序


