1. 集合简介
- Java集合大致可分为Set、List、Queue和Map
- 用于存储数量不等的对象
2. 集合详解
2.1 Collection接口
方法名 | 作用 |:---:|:---:| boolean add(Object o)
|向集合中添加元素 boolean addAll(Collection c)
|向集合中添加元素 void clear()
|清除所有元素 boolean contains(Object o)
|是否包含指定元素 boolean containsAll(Collection c)
|是否包含c里面的所有元素 boolean remove(Object o)
|移除指定元素 Iterator iterator()
|返回一个迭代对象 int size()
|集合元素的个数 Object[] toArray()
|转化成一个数组 removeIf(Predicate)
|转化成一个数组
- Predicate的用法
ArrayList<String> list = new ArrayList<>();
list.add("一本书");
list.add("123");
list.add("1455555555");
System.out.println(calAll(list,el -> ((String)el).length()>3));
public static int calAll(Collection books, Predicate predicate){
int total = 0;
for(Object o: books){
if(predicate.test(o)){
total += 1;
}
}
return total;
}
2.2 Iterator接口
方法名 | 作用 |:---:|:---:| forEach()
|遍历集合 hasNext()
|被迭代的元素是否还没被迭代完 next()
|被迭代的下一个元素 remove()
|删除集合里上一次next方法返回的元素 forEachRemaining()
|删除集合里上一次next方法返回的元素
ArrayList a = new ArrayList();
a.add("123");
a.add("12345");
a.forEach(obj ->{
System.out.println(obj);
});
2.3 Set集合
- 与Collection基本相同
- 区别:Set不允许有重复的元素
2.3.1 HashSet类
- 不能保证元素的排列顺序,有可能发生变化
- 不是同步的,如果多个线程同时访问一个
HashSet
,则必须保证其同步 - 集合元素值可以是
null
- 两个对象相等的条件是
equals
方法和hashCode
方法返回值相同
2.3.2 LinkedHashSet类
- HashSet子类,也是根据元素的hashCode值来决定元素的存储位置
- 用链表维护元素的次序,访问顺序和插入顺序一致
- 需要维护次序,所以性能略低于HashSet
2.3.3 TreeSet类
- SortedSet接口的实现类,可以保证集合元素处于排序状态
- 认定两个元素相同的条件是compareTo返回0
- 额外方法
方法名 | 作用 |:---:|:---:| first()
|集合第一个元素 last()
|集合最后一个元素 lower(Object o)
|指定元素之前的元素,o不需要是TreeSet之中的 higher(Object o)
|指定元素之后的元素,o不需要是TreeSet之中的 subSet(fromElement,toElement)
|Set的子集合
- 支持两种排序方法:自然排序和定制排序
1. 自然排序: - Java提供了一个Comparable接口,定义了一个compareTo方法,来表示二者是否相等 - 被加入的元素必须已经实现了Comparable接口,否则会抛出异常 - 向TreeSet中加入的应该是同一种类型的对象
2. 定制排序: - 使用lambda表达式来定制TreeSet的排序规则
String str1 = "123";
String str2 = "1234";
TreeSet ts = new TreeSet((o1,o2)->{
return ((String)o1).length() == ((String)o2).length()? 0:-1;
});
ts.add(str1);
ts.add(str2);
System.out.println(ts);
2.3.4 EnumSet类
- 专门为枚举类设计的集合类,所有的元素必须是指定枚举类型的枚举值
- 内部以位向量的形式储存,所以非常高效,紧凑,占用内存小,运行效率高
- 不允许加入null元素
- 没有构造器,需要通过类方法来创建
方法名 | 作用 |:---:|:---:| allOf(Class elementType)
| 创建一个包含指定枚举类所有枚举值的EnumSet集合 complementOf(EnumSet)
| EnumSet剩下的枚举类中有的 copyOf(Collection c)
| 用Collection创建EnumSet noneOf(Class elementType)
| 创建一个空的EnumSet,集合元素是elementType类型
2.3.5 Set性能比较
- HashSet总体性能比TreeSet好
- LinkedHashSet在增删改操作上比HashSet慢,但遍历操作块
- EnumSet性能最好,但只能保存同一个枚举类的枚举值
2.4 List集合
- List集合代表一个元素有序,可重复的集合,每一个元素都有索引
- 默认按照添加的顺序设置元素的索引
- equals返回true则两个对象相等
List接口新方法 方法名 | 作用 |:---:|:---:| add(int index, Object element)
| 指定位置插入指定元素 addAll(int index, Collection element)
| 指定位置插入指定元素集合 get(int index)
| index索引处的元素 indexOf(Object o)
| 对象o在List集合中第一次出现的位置 lastIndexOf(Object o)
| 对象o在List集合中最后一次出现的位置 remove(int index)
| 删除并返回index索引处的元素 sort(Comparator c)
| 排序
ListIterator新方法 方法名 | 作用 |:---:|:---:| hasPrevious
| 是否有前项 previous
| 返回迭代器上一个元素 add
| 往迭代器加入一个元素
2.4.1 ArrayList
- 基于数组实现的List类,封装了一个动态的、允许再分配的Object[]数组
- List的主要实现类
- 线程不安全的,当多个线程访问同一个ArrayList集合时,需要手动保证集合的同步性
2.5 Queue集合
- 用于模拟队列,“先进先出”
- Queue接口方法
方法名 | 作用 |:---:|:---:| void add
| 将元素放入队列的尾部 boolean offer
| 将元素放入队列的尾部 element()
|获取队列头部的元素,但是不删除该元素 Object peek()
| 获取队列头部的元素,但是不删除该元素。如果此队列为空,则返回null Object poll()
| 获取队列头部的元素,删除该元素。如果此队列为空,则返回null Object remove()
| 获取队列头部的元素,删除该元素
- Deque接口
方法名 | 作用 |:---:|:---:| void addFirst(Object o)
| 将元素放入双端队列的开头 void addLast(Object o)
| 将元素放入双端队列的末尾 Object peekFirst()
| 获取队列头部的元素,但是不删除该元素。如果此队列为空,则返回null Object peekLast()
| 获取队列尾部的元素,但是不删除该元素。如果此队列为空,则返回null Object pollFirst()
| 获取队列头部的元素,删除该元素。如果此队列为空,则返回null Object pollLast()
| 获取队列尾部的元素,删除该元素。如果此队列为空,则返回null ...
| 一系列上述Queue接口中方法加上First/Last的方法 push(), pop(), peek()
| 一系列栈方法
2.5.1 LinkedList集合
- List集合,可以根据索引随机访问集合中的元素
- 实现了Deque接口,可以被当作双端队列来使用
2.6 Map集合
- 保存key和value,key的唯一条件是equals不返回true
- Map接口
方法名 | 作用 |:---:|:---:| void clear()
| 删除该Map对象中所有的key-value对 void containsKey(Object key)
| 是否包含指定key void containsValue(Object value)
| 是否包含指定value Set entrySet()
| key,Value组成的Set集合 Object put(Object key,Object value)
| 添加一个key-value Object remove(Object key)
| 删除一个key-value Collection values()
| 所有value组成的Collection Collection keySet()
| 键组成的Set
2.6.1 HashMap
- 可以使用null作为key或value
- 线程不安全,性能较高
HashMap map = new HashMap();
map.put("1","一");
map.put("2","二");
for(Object o :map.entrySet()){
System.out.println((((Map.Entry)o).getKey()));
}
2.6.2 LinkedHashMap
- 需要维护元素的插入顺序,因此性能略低于HashMap的性能
- 用链表维护顺序,在迭代时性能较好
2.6.3 SortedMap接口和TreeMap
- TreeMap是一个红黑树数据结构,每个key-value对即作为红黑树的一个节点
- TreeMap可以保证所有的key-value对处于有序状态
排序方式 1. 自然排序 2. 定制排序
3 Collections工具类
Collections对List集合元素操作
3.1 排序操作
方法名 | 作用 |:---:|:---:| void reverse(List list)
| 反转List void shuffle(List list)
| 随机排序List void sort(List list)
|根据元素的自然顺序对指定List集合的元素按自然顺序排序 void sort(List list, Comparator c)
| 根据元素的定制顺序对指定List集合的元素按自然顺序排序 void swap(List list, int i, int j)
| 交换List中的i和j处的元素 void rotate(List list, int distance)
| 当distance为正数时,将list集合的后distance个元素整体移到前面;当distance为负数时,将list集合的前distance个元素整体移到后面
ArrayList al = new ArrayList();
for(int i = 1; i<50;i++){
al.add("number is " + i);
}
Collections.reverse(al);
System.out.println(al); //翻转List
Collections.shuffle(al); //List随机排序
3.2 查找、替换操作
方法名 | 作用 |:---:|:---:| int binarySearch(List list, Object key)
| 使用二分搜索法搜索指定的List集合,以获得指定对象在List中的索引 Object max(Collection coll)
| 根据元素的自然顺序,返回给定集合中的最大元素 Object max(Collection coll, Comparator comp)
| 根据comparator顺序,返回给定集合中的最大元素 Object min(Collection coll)
| 根据元素的自然顺序,返回给定集合中的最小元素 Object min(Collection coll, Comparator comp)
| 根据comparator顺序,返回给定集合中的最小元素 int frequency(Collection c, Object o)
| 返回o在c中出现的次数
3.3 同步控制
- Java集合中如HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap和TreeMap都是线程不安全的
Collections.synchronizedList(al);
Set set = Set.of("Java","Kotlin","Go","Swift");
System.out.println(set);
//以下将导致错误
set.add("123");