java集合
目录
1. Java集合概述
2. List集合
3. Map集合
4. Properties
5. Set集合
6. Queue
7. PriorityQueue
8. Deque
9. Stack
1. Java集合概述
Java集合设计特点:
- 接口和实现相分离:List接口——ArrayList、LinkedList
- 支持泛型:List<String> list= new ArrayList<>();
- 访问集合有统一的方法:迭代器Iterator
遗留类:
- Hashtable:一种线程安全的Map实现
- Vector:一种线程安全的List实现
- Stack:基于Vector实现的LIFO栈
遗留接口:
- Enumeration<E>:已被Iterator<E>取代
总结
- Java集合类定义在java.util包中
- 常用的集合类包括List、Set、Map
- Java集合使用统一的Iterator遍历集合
- 尽量不要使用遗留接口
2. List集合
List和Array转换
把List<E>变为Array:
- Object[ ] toArray()
- <T> T[ ] toArray(T[ ] a)
把Array变为List<E>:
- <T> List<T> Arrays.asList(T...a) —— 伪不可修改
- 通过避免使用原始集合来实现真正不可修改
总结List特点
- 按索引顺序访问的长度可变的链表
- 优先使用ArrayList而不是LinkedList
- 可以直接使用for...each遍历
- 可以和Array互相转换
List查找总结
- List的实现类通过元素的equals方法比较两个元素
- 放入的元素必须正确覆写equals方法,JDK提供的String、Integer等已经覆写了equals方法
- 编写equals方法可借助Object.equals( )判断
注:如果不在List中查找元素,不必覆写equals方法
3. Map集合
遍历Map:
- 遍历Key可以使用for...each循环遍历KeySet()
- 同时遍历Key和Value可以使用for...each循环遍历entrySet()
最常用的实现类是HashMap,HashMap内部存储不保证有序:
- 遍历时的顺序不一定是put放入的顺序,也不一定是Key的排序顺序
SortMap保证遍历时以Key的顺序排序:
- SortedMap的实现类是TreeMap
- TreeMap按Key顺序排序,可以自定义排序算法:
HashCode和equals
Map是一种键-值映射表:
- HashMap通过计算Key的hashCode()定位Key的存储位置,继而获得Value
正确使用Map必须保证:
- 作为Key的对象必须正确覆写equals()方法
- 作为Key的对象必须正确覆写hashCode()方法:
如果两个对象相等,则两个对象的hashCode()必须相等;
如果两个对象不相等,则两个对象的hashCode()不需要相等;
以上截图来自HashMap类中的get(key)方法中调用的getNode(int Object)方法,证实了map集合在操作的时候要同时保证hashCode和equals都相同才可进行相应的操作。
如果一个对象覆写了equals()方法,就必须正确覆写hashCode()方法:
- 如果a.equals(b)==true,则a.hashCode()==b.hashCode() —— 必须要满足
- 如果a.equals(b)==false,则a和b的hashCode()尽量不要相等 —— 避免map冲突提升效率
4. Properties
Properties用于读取配置:
- properties文件只能使用ASCII编码
- 可以从文件系统读取.properties文件
- 可以从ClassPath读取.properties文件
- 可以读取多个.properties文件,后读取的Key-Value会覆盖已读取的K-V
提示:在ClathPath中配置默认配置,在文件系统的配置更改的配置
Properties实际上是从Hashtable派生:
提示:不要调用get、put方法;仅使用getProperty() / setProperty()方法
5. Set集合
Set<E>用于存储不重复的元素集合:
- Set实际上相当于不存储Value的map
- Set用于去除重复元素
- 放入Set的元素要正确实现equals()和hashCode()
Set不保证有序:
- HashSet是无序的
- TreeSet是有序的
- 实现了SortedSet接口的是有序Set
- TreeSet按元素顺序排序,可以自定义排序算法:
- Set转为ArrayList
总结
- Set用于存储不重复的元素集合
- 放入Set的元素与作为Map的Key要求相同:正确实现equals()和hashCode()
- 利用Set可以去除重复元素
- 遍历SortedSet按照元素的排序顺序遍历,也可以自定义排序算法
6. Queue
Queue<E>实现一个FIFO队列:
- LinkedList实现了Queue<E>接口
- 获取队列长度:size()
- 添加元素到队尾:boolean add(E e) / boolean offer(E e)
- 获取队列头部元素并删除:E remove() / E poll()
- 获取队列头部元素但不删除:E element() / E peek()
- 当添加或获取元素失败时:
提示:避免把null添加到队列
7. PriorityQueue
PriorityQueue<E>的出队顺序与元素的优先级有关:
- remove() / poll() 总是取优先级最高的元素
- 添加元素到队尾:boolean add(E e) / boolean offer(E e)
- 获取队列头部元素并删除:E remove() / E poll()
- 获取队列头部元素但不删除: E element() / E peek()
- PriorityQueue<E> 具有Queue<E> 接口:获取队首元素时总是返回优先级最高的元素
priorityQueue必须实现comparable接口或Comparator内部类:
总结
- PriorityQueue<E> 实现一个优先队列
- 从队首获取元素时,总是获取优先级最高的元素
- 默认按元素比较的顺序排序(必须实现Comparable接口)
- 可以通过Comparator自定义排序算法(不必实现Comparable接口)
8. Deque
Deque<E>是新啊一个双端队列:
- 既可以添加到队尾,也可以添加到队首
- 既可以从队首获取,又可以从队尾获取
Deque使用技巧:
- 使用Deque<E>的时候总是调用xxxFirst() / xxxLast()方法
- Deque的实现类:ArrayDeque、LinkedList
注意:避免把null添加到Deque
9. Stack
背景:Java中已存在一个Stack类,兼容性的考虑就没有创建Stack接口
用Deque可以实现Stack的功能:
- push(E e):addFirst(E e)
- pop():removeFirst()
- peek():peekFirst()
Stack的作用:
- 方法的嵌套调用,嵌套调用过多会造成栈溢出StackOverflowError
- 进行+ - * / 运算
整个流程(只截取了运行代码)还是有点复杂的,这里简单介绍以下操作流程:
1. 提供中缀表达式1+2*(9-5)
2. 转换为后缀形式1 2 9 5 - * +,按顺序将1295入栈
3. 当遇到运算符(-)时就相应的从栈中抛出两个数(5 9)
4. 进行运算(9-5),然后将运算后的结果(4)push会栈中
5. 之后重复3和4步骤,至栈为空结束
总结
- 栈是一种LIFO的数据结构
- 操作栈的元素的方法:push(E e); pop(); peek();
- java使用Deque实现栈的功能,注意之调用push / pop / peek,避免调用deque的其他方法
- 不要使用遗留类Stack