一、集合
Java集合类存放于 java.util 包中,是一个用来存放对象的容器。
- 集合只能存放对象。比如你存一个 int 型数据 1放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。
- 集合存放的是多个对象的引用,对象本身还是放在堆内存中。
- 集合可以存放不同类型,不限数量的数据类型。
1、集合的结构
2、集合与数组
二、Collection
1、List
有序可重复
1.1、ArrayList:数组实现,查询快,增删慢,轻量级;(线程不安全)
- 底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点
- 它具有方法add()、remove()、contains()、size()等
1.2、LinkedList:双向链表实现,增删快,查询慢 (线程不安全)
- LinkedList是采用双向循环链表实现的。
- 利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。
- 它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等。
- 经常用在增删操作较多而查询操作很少的情况下
1.3、Vector :数组实现,重量级 (线程安全、使用少)
- 与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多
- 线程安全,效率低
2、Set
无序不可重复
2.1、HashSet:采用哈希算法,底层用数组存储数据
- 底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高
- HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束
- HashSet需要同时通过equals和HashCode来判断两个元素是否相等,具体规则是,如果两个元素通过equals为true,并且两个元素的hashCode相等,则这两个元素相等(即重复)
2.2、TreeSet:底层数据结构采用二叉树来实现,元素唯一
- 底层是二叉树(红黑树的树据结构)实现的,Treeset中的数据是自动排好序的,不允许放入null值
- TreeSet的排序分两种类型,一种是自然排序,另一种是定制排序
适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为快速查找而设计的Set,我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。
3、Iterator
迭代器,遍历集合使用
- hasNext():判断是否还有下一个元素
- next():①指针下移;②将下移以后集合位置上的元素返回
Iterator it = c.iterator;
while(it.hasNext()){
Object o = it.next();
}
三、Map
1、HashMap
键值对,key不能重复,但是value可以重复;key的实现就是HashSet;value对应着放;允许null的键或值;
- jdk1,7 数组+链表
- jdk1,8 数组+链表+红黑树,数组的某一个索引位置上的元素以链表形式存在的数据个数>8 且 当前数组的长度 > 64时,此时索引位置上的所有数据改为使用红黑树存储。
- HashMap 是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。
- HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;
- HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。
- 和Hashset 一样,利用key 的hashCode 值进行排序;
2、TreeMap
对key排好序的Map; key 就是TreeSet, value对应每个key
- 是一个红黑树结构,对key 进行排序
- TreeMap存储 Key-Value 对时,需要根据 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。
- TreeMap判断两个key相等的标准:两个key通过compareTo()方法或者compare()方法返回0
3、适用场景分析:
- HashMap:适用于Map中插入、删除和定位元素。
- Treemap: 适用于按自然顺序或自定义顺序遍历键(key)。
四、Collections工具类
Collections 是一个操作 Set、List 和 Map 等集合的工具类
1、常用的方法:
- reverse(List):反转 List 中元素的顺序
- shuffle(List):对 List 集合元素进行随机排序
- sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
- swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
- Object max/min(Collection):根据元素的自然顺序,返回给定集合中的最大/最小元素
- int frequency(Collection,Object):返回指定集合中指定元素的出现次数
- boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List 对象的所有旧值
2、Collection和Collections的区别
- java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。
- java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
五、泛型
泛型就是参数化类型,也就是说所操作的数据类型被指定为一个参数
- 适用于多种数据类型执行相同的代码
- 泛型中的类型在使用时指定
- 泛型归根到底就是“模版”
优点:使用泛型时,在实际使用之前类型就已经确定了,不需要强制类型转换。提高Java程序的类型安全。
public class EmployeeDao {
//模拟数据库的数据
private static Map<Integer, Employee> employees = null;
//员工有所属的部门
@Autowired
private DepartmentDao departmentDao;
static {
employees = new HashMap<Integer,Employee>();
employees.put(1001,new Employee(1001,"AA","2315792654@qq.com",1,new Department(101,"教学部")));
employees.put(1002,new Employee(1002,"BB","2315792655@qq.com",0,new Department(102,"市场部")));
employees.put(1003,new Employee(1003,"CC","2315792656@qq.com",1,new Department(103,"教研部")));
employees.put(1004,new Employee(1004,"DD","2315792657@qq.com",0,new Department(104,"运营部")));
employees.put(1005,new Employee(1005,"EE","2315792658@qq.com",1,new Department(105,"后勤部")));
}
//主键自增加
private static Integer initId = 1006;
//增加一个员工
public void save(Employee employee){
if(employee.getId() == null){
employee.setId(initId++);
}
employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
employees.put(employee.getId(),employee);
}
//查询全部的员工信息
public Collection<Employee> getAll(){
return employees.values();
}
//通过ID查询员工
public Employee getEmployeeById(Integer id){
return employees.get(id);
}
//通过ID删除员工
public void delete(Integer id){
employees.remove(id);
}
}