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)  ——  伪不可修改

GRPC 集合与java映射关系_Java

  • 通过避免使用原始集合来实现真正不可修改

GRPC 集合与java映射关系_List_02

总结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()

GRPC 集合与java映射关系_Java_03

  • 同时遍历Key和Value可以使用for...each循环遍历entrySet()

GRPC 集合与java映射关系_Stack_04

最常用的实现类是HashMap,HashMap内部存储不保证有序:

  • 遍历时的顺序不一定是put放入的顺序,也不一定是Key的排序顺序

SortMap保证遍历时以Key的顺序排序:

  • SortedMap的实现类是TreeMap

GRPC 集合与java映射关系_GRPC 集合与java映射关系_05

  • TreeMap按Key顺序排序,可以自定义排序算法:

GRPC 集合与java映射关系_Stack_06

HashCode和equals 

Map是一种键-值映射表:

  • HashMap通过计算Key的hashCode()定位Key的存储位置,继而获得Value

GRPC 集合与java映射关系_List_07

正确使用Map必须保证:

  • 作为Key的对象必须正确覆写equals()方法
  • 作为Key的对象必须正确覆写hashCode()方法:

如果两个对象相等,则两个对象的hashCode()必须相等;

如果两个对象不相等,则两个对象的hashCode()不需要相等;

GRPC 集合与java映射关系_Stack_08

以上截图来自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冲突提升效率

GRPC 集合与java映射关系_Java_09

4. Properties 

Properties用于读取配置:

  • properties文件只能使用ASCII编码

GRPC 集合与java映射关系_Java_10

  • 可以从文件系统读取.properties文件

GRPC 集合与java映射关系_List_11

  • 可以从ClassPath读取.properties文件

GRPC 集合与java映射关系_List_12

  • 可以读取多个.properties文件,后读取的Key-Value会覆盖已读取的K-V

GRPC 集合与java映射关系_Java_13

提示:在ClathPath中配置默认配置,在文件系统的配置更改的配置

Properties实际上是从Hashtable派生:

GRPC 集合与java映射关系_GRPC 集合与java映射关系_14

GRPC 集合与java映射关系_Java_15

提示:不要调用get、put方法;仅使用getProperty() / setProperty()方法

5. Set集合

Set<E>用于存储不重复的元素集合:

  • Set实际上相当于不存储Value的map
  • Set用于去除重复元素
  • 放入Set的元素要正确实现equals()和hashCode()

Set不保证有序:

  • HashSet是无序的
  • TreeSet是有序的
  • 实现了SortedSet接口的是有序Set

GRPC 集合与java映射关系_List_16

  • TreeSet按元素顺序排序,可以自定义排序算法:

GRPC 集合与java映射关系_GRPC 集合与java映射关系_17

  • Set转为ArrayList

GRPC 集合与java映射关系_List_18

总结

  • Set用于存储不重复的元素集合
  • 放入Set的元素与作为Map的Key要求相同:正确实现equals()和hashCode()
  • 利用Set可以去除重复元素
  • 遍历SortedSet按照元素的排序顺序遍历,也可以自定义排序算法

 

6. Queue 

Queue<E>实现一个FIFO队列:

  • LinkedList实现了Queue<E>接口

GRPC 集合与java映射关系_Java_19

  • 获取队列长度:size()
  • 添加元素到队尾:boolean add(E e) / boolean offer(E e)
  • 获取队列头部元素并删除:E remove() / E poll()
  • 获取队列头部元素但不删除:E element() / E peek()
  • 当添加或获取元素失败时:

GRPC 集合与java映射关系_Stack_20

提示:避免把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> 接口:获取队首元素时总是返回优先级最高的元素

GRPC 集合与java映射关系_Java_21

priorityQueue必须实现comparable接口或Comparator内部类:

GRPC 集合与java映射关系_GRPC 集合与java映射关系_22

GRPC 集合与java映射关系_GRPC 集合与java映射关系_23

总结

  • PriorityQueue<E> 实现一个优先队列
  • 从队首获取元素时,总是获取优先级最高的元素
  • 默认按元素比较的顺序排序(必须实现Comparable接口)
  • 可以通过Comparator自定义排序算法(不必实现Comparable接口)

8. Deque

Deque<E>是新啊一个双端队列:

GRPC 集合与java映射关系_GRPC 集合与java映射关系_24

  • 既可以添加到队尾,也可以添加到队首
  • 既可以从队首获取,又可以从队尾获取 

GRPC 集合与java映射关系_Stack_25

GRPC 集合与java映射关系_List_26

Deque使用技巧:

  • 使用Deque<E>的时候总是调用xxxFirst() / xxxLast()方法

GRPC 集合与java映射关系_GRPC 集合与java映射关系_27

  • Deque的实现类:ArrayDeque、LinkedList

GRPC 集合与java映射关系_GRPC 集合与java映射关系_28

注意:避免把null添加到Deque

9. Stack

背景:Java中已存在一个Stack类,兼容性的考虑就没有创建Stack接口

用Deque可以实现Stack的功能:

GRPC 集合与java映射关系_Java_29

  • push(E e):addFirst(E e)
  • pop():removeFirst()
  • peek():peekFirst()

Stack的作用:

  • 方法的嵌套调用,嵌套调用过多会造成栈溢出StackOverflowError

GRPC 集合与java映射关系_Stack_30

  • 进行+ - * / 运算

GRPC 集合与java映射关系_List_31

整个流程(只截取了运行代码)还是有点复杂的,这里简单介绍以下操作流程:

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