集合
一.简介
1.概念
集合就是用存储多个元素的,动态的扩张长度,弥补了数组固定大小的缺陷。
2. 存储结构
集合的存储结构,分为两种:
-
顺序存储
将集合中的元素依次存放在某个区域中,称为顺序存储,在内存中分配的空间是连续的
特性: 访问效率高,插入和删除效率低
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S1BHGLlv-1610939894401)(img/顺序存储.png)]
-
链表存储(链式)
在内存中分配的空间可以是不连续的
分为: 单向链式 和双向链式
特性: 插入和删除效率高,访问效率低
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rZ8eqLbp-1610939894420)(img/单项链式.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1A79ydn9-1610939894427)(img/双向项链式.png)]
3.集合类和接口
集合相关的类和接口都在java.util包中
Collection 接口
List 接口
ArrayList 实现类
LinkedList 实现类
Vector 实现类
Stack
Set 接口
HashSet 实现类
TreeSet 实现类
Map 接口 键值对集合
HashMap 实现类
HashTable 实现类
Properties
二.List
特点: 有序的, 可重复
实现类:ArrayList 、LinkedList Vector Stack
1.ArrayList
1.1.简介
ArrayList 是实现了长度可变的数组
- 本质上使用的就是数组实现,数组的默认长度为10
- 存储结构:顺序存储
- 特点: 访问效率高,插入和删除效率低
1.2常用方法
list.add(2, "alice");// 指定的索引位置添加
//set()修改
String str = list.set(0, "lucy");// 修改指定的元素,返回被修改的元素
System.out.println(str);
//remove
list.remove(1);// 根据索引删除,返回值为被删除的元素
boolean b = list.remove("jack");//根据元素删除,返回值为 true/false
System.out.println(b);
System.out.println(list);
//get() 通过索引获取 size() 大小
// indexOf() 查询元素的索引位置
System.out.println(list.indexOf("jery"));
//contains()是否包含指定元素
System.out.println(list.contains("alice"));
// isEmpty() 是否为空
list.isEmpty();
// clear()清空
// toArray() 将集合转为数组
Object[] array = list.toArray();
System.out.println(Arrays.toString(array));
//将数组转为 固定长度的集合
String[] arr = {"aa","bb","cc"};
List<String> asList = Arrays.asList(arr);
System.out.println(asList);
asList.add("DD");//会报错
2.Vector
Vector 和 ArrayList 相似,都是使用数组实现的,用法基本相同
区别:
Vector:
- 同步线程,线程安全的
- 执行效率低,影响性能
ArrayList:
- 异步线程,线程不安全的
- 执行效率高
3.LinkedList
当需要频繁对集合中的数据进行插入和删除时就使用LinkedList
- 存储结构:双向链式存储
- 特点: 插入和删除效率高,访问效率低
常用方法: 具有List接口中的所有方法,同时具有几个额为的方法
addFirst() addLast() getFirst() getLast() removeFirst () removeLast()
4.Stack
继承了Vector
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TuktJMsn-1610939894435)(img/Stack.png)]
特点: 先进后出
Stack<String> stack = new Stack<String>();
stack.push("a");
stack.push("b");
stack.push("c");
//出栈
System.out.println(stack.pop());//c
//peek 查看栈顶的元素
System.out.println(stack.peek());//b c被取出了
System.out.println(stack);
三.Set
特点: 无序的(放入与输出的顺序不一致), 不可重复
1.HashSet
1.1基本用法
HashSet是一种哈希算法的集合
-
数据结构: 哈希表,哈希散列表
-
特点 :操作速度快,根据哈希算法快速定位元素的存放位置
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OMA0gS5q-1610939894438)(img/哈希表.png)]
HashSet<String> set = new HashSet<String>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
set.add("aaa");// 相同元素不会添加到集合中
System.out.println(set);
/**
* set集合
* add() size() remove 等都有,但是没有关于填入下标的方法
* set集合不能用下标访问,不能使用 普通的for循环进行遍历
*/
for (String s : set) {
System.out.println(s);
}
// addAll 添加一个集合 --- 可以用对list集合进行去重 list集合转为 了set集合
List<String> list = Arrays.asList(new String[]{"a","b","c","d","d","a"});
set.addAll(list);
System.out.println(set);
//使用构造方法将 list转为set集合
HashSet<String> set2 = new HashSet<String>(list);
System.out.println(set2);
1.2 HashSet如何判重
-
添加元素时,调用该对象的hashcode()方法,获取一个哈希值
-
根据哈希值,使用哈希算法确定一个哈希表中的位置
-
如果该位置没有元素,则直接放入
-
如果该位置有元素了,则调用两个对象的equals方法进行比较
true: 则认为是同一个对象,无法添加,舍弃当前对象
false:则认为不是同一个对象,以链式结构向当前位置进行追加,改变了哈希表的结构,会影响性能。
总结:
- 判断重复的依据,两个对象hashCode值一致,并且equals也返回true ---- 同一个对象—集合中只能添加一个进去
- 在set集合中防止相同对象被添加,需要 hashCode 和 equals都 重写
2.TreeSet
2.1基本用法
用于对元素排序的有序集合
- 数据结构:二叉树
- 特点:元素有大小顺序
2.2排序
排序:
-
元素会根据自然顺序排列
存入的元素不具有自然顺序 ,集合会报错 ----- 该对象不可比较
解决: 让元素可以比较,将要比较的对象实现一个Comparable接口,表示该类型的对象可以比较
并且重写compareTo()方法,指定具体的比较规则
-
提供一个比较器,根据比较器进行排序
定义一个比较器,就是定义一个实现了Compartor 接口的类,实现compare()方法
在创建集合是,将比较器传入。
注意:TreeSet判断重复的依据: 但添加的两个元素的compareTo() 或者 是 compare()方法 返回0时,就认为两个对象相同了,只会添加一个到集合中
四.Map
Map是用来存储键值对数据的集合, 根据key操作对应的value
- 是一种对应关系 key— value
- key必须是唯一的,不能重复
- 无序,放入与输出的顺序不一致,不能够通过索引操作map集合中的数据
1.HashMap
- 数据结构:哈希表
- 特点: 操作速度快
1.1常用方法
方法 | 含义 |
---|---|
put() | 添加元素 |
get() | 通过key,获取value |
keySet() | 获取所有的key值,返回一个set集合 |
values() | 获取所有的value 返回一个集合 |
containsKey() | 判断是否包含指定的key |
containsValue() | 判断是否包含指定的value |
remove() | 删除,返回被删除的元素 |
1.2map集合的遍历
- 通过keySet()方法获取所有的key的集合,遍历key
- 通过values()方法,获取所有的value的集合,遍历value
- 通过entrySet()方法,获取key-value的集合
2.HashTable
HashTable 与 HashMap用法一致
区别:
HashMap:
- key和value都可以为null
- 异步线程,线程不安全,效率高
Hashtable:
- key和value都不能为null;
- 同步线程,线程安全,效率较低
3.Properties
继承了Hashtable,也是键值对集合,一般只用来方法字符串的键值对
属性文件(配置文件):
- 以.properties 作为后缀名的文件
- 内容格式: key=value 属性名=属性值 如: name=张三 (没有空格,逗号,分号,不要有空行)
- 默认的字符集为ISO-8859-1, 不支持中文的,eclipse会自动转码
五.Collections类
1.简介
集合中工具列,提供了操作集合的方法
类似于Arrays工具类
2.方法
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(10);
list.add(15);
list.add(11);
Collections.addAll(list, 111,222,333);
System.out.println(list);
//max min
System.out.println(Collections.max(list));
//reverse()反转
Collections.reverse(list);
//replaceAll()
Collections.replaceAll( list, 111, 666);
//swap
Collections.swap(list, 0, list.size()-1);
System.out.println(list);
// sort() 排序
Collections.sort(list);
System.out.println(list);
List<User> list2 = new ArrayList<User>();
list2.add(new User(1,12));
list2.add(new User(2,22));
list2.add(new User(3,16));
list2.add(new User(4,19));
/***User 实现Comparable接口******/
// Collections.sort(list2);
/***提供比较器****/
Collections.sort(list2, new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o2.getAge()-o1.getAge();//根据年龄从大 到小
}
});
System.out.println(list2);
总结:
- 集合相关的接口和类
- List 和 Set 的特点
- ArrayList LinkedList Vector 异同
- HashMap 与Hashtable的区别