Java的集合(list、set、map)非常重要,竞赛和开发经常会用到,同时也是教学和考试的重点,接下来我将介绍这三个集合的知识。
list:
可重复(允许元素重复)、有序(存取顺序一致)、单列集合、有索引(可以通过下标 get(i) 取值),他和数组的区别就是数组是开辟一块连续的内存,开辟多少最多就只能用多少,list(set、map)只可以存放引用类型(包括包装类、String、自定义对象),长度可变自动扩容。
常用实现类
-
ArrayList(最常用)
- 底层:动态数组
- 查询快、增删慢
- 线程不安全
- 默认初始容量 10,扩容 1.5 倍
-
LinkedList
- 底层:双向链表
- 增删快、查询慢
- 适合频繁插入、删除
- 线程不安全
List 常用方法
list.add();//添加一个元素
list.get(index);//获取下标为index的元素
list.remove(index);//移除下标为index的元素
list.size();//获取list的大小(长度)
list.contains();//判断list是否包含某个元素
set:
无序(存取顺序不一致)、不可重复(自动去重)、无索引(不能用下标取值)、单列集合
常用实现类
-
HashSet
- 底层:HashMap 封装
- 无序、去重
- 线程不安全
- 去重依赖:
hashCode() + equals()
-
LinkedHashSet
- 底层:哈希表 + 双向链表
- 保留插入顺序,又能去重
-
TreeSet
- 底层:红黑树
- 自动升序排序
- 可自定义比较器
Set 常用方法
和list类似(没有get方法)
Map 集合
双列存储 :key + value、key 唯一不可重复 ,value 可重复、无序(HashMap)
常用实现类
-
HashMap(最常用)
- 底层:数组 + 链表 + 红黑树
- JDK1.8 链表长度≥8 转红黑树
- 无序、线程不安全
- 默认容量 16,负载因子 0.75
-
LinkedHashMap
- 保留插入顺序
- 可做 LRU 缓存
-
TreeMap
- 底层红黑树
- key 自动排序
Map 常用方法
map.put(key,value);//添加元素
map.get(key);//获取key对应的value
map.remove(key);
map.containsKey(key);//是否包含某个键
map.keySet(); // 获取所有key
对比表
|------|--------|---------|-----|
| 集合 | 有序 | 可重复 | 有索引 |
| List | 有序 | 可重复 | 下标 |
| Set | 无序 | 不可重复 | 无下标 |
| Map | key 无序 | key 不重复 | 无下标 |
嵌套用法
这三个可以互相嵌套使用:
List<List<Integer>> list = new ArrayList<>();//场景:二维表、嵌套列表、分组数据
List<Set<String>> list = new ArrayList<>();//场景:每组内部自动去重
Map<Integer, List<Water>> map = new HashMap<>();//场景:分组,比如 分类 id → 对应多条数据
排序
Map和Set不能直接排序,可以先转为List再进行排序
// 升序
Collections.sort(list);
// 或
list.sort(Comparator.naturalOrder());
//降序
list.sort(Comparator.reverseOrder());
//自定义对象排序(重点)
class Person{
public String name;
public int age;
}
// 按年龄升序
list.sort((u1,u2) -> u1.age - u2.age);
// 按年龄降序
list.sort((u1,u2) -> u2.age - u1.age);
//升序就是前减后,降序是后减前
//自定义排序(重写compare)
//返回 负数:o1 放前面
//返回 正数:o2 放前面
//返回 0:顺序不变
List<Person> list = new ArrayList<>();
list.add(new Person("张三", 20));
list.add(new Person("李四", 18));
list.add(new Person("王五", 25));
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
// 升序:o1.age - o2.age
return o1.getAge() - o2.getAge();
//这里可自定义排序方法
}
});