List有序可重复
ArriveList : 查询快,底层是数组
Linkedlist: 添加删除元素快,地层是双向链表
Set 无序不可重复
HashSet : 底层是散列表
TreeSet : 底层是红黑树,元素必须有序
Map 无序 key不能重复 value能重复,保留映射关系
HashMap:底层是散列表
TreeMap : 底层是红黑树,元素必须有序
1.散列表
1.1 概述
散列表在本质上是一个数组。我们知道数组可以根据下标来进行随机访问,如a[0], a[1], a[2], a[3], a[4],通过这样来访问,因此其查询效率非常高。而在散列表中,当我们给出一个key的时候,也能立即查询到对应的value。这时我们就需要一个“中转站”,通过某种方式,把Key和数组下标进行转换,而这个中转站就是哈希函数
1.2. HashSet
当我们使用HashSet的时候,就等于是在使用HashMap
添加数据的时候,虽然调用的是HashSet,的add方法,但本质还是调用map的put方法
而map中需要保存的是k和v的映射关系,所以在set中有一个变量保存了value的值,所以我们在进行
set添加的时候,只操作了map中的key, value值我们不在关心
2 Map
2.1. 概述
Map是无序的,并且保存的是K-V键值对映射关系.其中K不能重复,V可以重复
HashMap :底层是散列表
TreeSet : 底层是红黑树,元素必须按照一定的规则进行排序
映射关系 : 比如商品和购买数量 商品为K 购买数量为V
* 散列表 : 用于存储键值对映射关系(K-V) , 存储方式为数组中保存链表,用于解决哈希冲突问题
* java中 散列表 对应的就是 HashMap
* 但是1.8开始,为了提高查询效率,引入了红黑树
* 想要把数据添加在散列表中,需要根据key生成hash值(java中指的hashCode方法),然后根据算法得到数组下标
* 如果下标中没有对应的数据,则添加到数组中即可
* 如果下标中有对应的数据,则需要调用要添加的key和对应的数据进行比较(equals),如果发生重复,则value值替换
* 如果不重复,说明是hash冲突,则把k-v插入的对应的链表中(节点对象中,包含4个属性: hash值,key,value,next)
* 相同对象生成多次hash,一定是相同的值,但是不同对象也有可能生成相同的hash值,叫哈希冲突
2.2 继承体系
2.3 常用方法
2.4.HashMap
package Map;
import java.util.HashMap;
import java.util.Map;
public class HashMap_01 {
public static void main(String[] args) {
Map map=new HashMap();
//增加,key不可重复,如果key重复,则value进行替换
map.put("a", 1);
map.put("A", 2);
map.put('A', 3);
map.put(65, 4);
map.put('A', 5);
//删除 删除key值
map.remove(65);
//改 ,key值不能修改,只能修改value
//如果key值不存在,则视为添加操作,如果存在则修改
map.put("a", 5);
//查 根据key值查询value
System.out.println(map.get("A"));
// 个数
System.out.println(map.size());
// 是否为空
System.out.println(map.isEmpty());
// 是否包含某个key
System.out.println(map.containsKey(""));
// 是否包含某个value
System.out.println(map.containsValue(""));
// 清空
map.clear();
}
}
package Map;
import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
/**
* map不能直接遍历
* @author
*
*/
public class HashMap_02 {
public static void main(String[] args) {
HashMap map =new HashMap();
map.put("a1", 1);
map.put("a2", 2);
map.put("a3", 3);
map.put("a4", 4);
map.put("a5", 5);
map.put("a6", 6);
//value()获取所有的value
Collection values=map.values();
for (Object object : values) {
System.out.println(object);
}
//把key取出,保存在set中
Set set=map.keySet();
for (Object object : set) {
// System.out.println(object);
System.out.println(object + " : " + map.get(object));
}
//把map转换为多个entry对象并保存在set中
System.out.println("--------------------");
Set entrys=map.entrySet();
for (Object obj : entrys) {
//覆写toString方法 会议key=value形式打印
// System.out.println(obj);
Entry entry=(Entry) obj;
System.out.println(entry.getKey()+" = "+entry.getValue());
}
// map.forEach((x,y) ->{
// System.out.println(x + "= "+ y);
// });
// map.entrySet();
}
}
3 泛型
3.1. 概述
* 泛型:类型检查
* 没有使用泛型 集合中可以存放任意类型的数据,均会转型为object类型
* 优点:什么都能做
* 缺点: 由于什么都能做,导致获取数据是,得到的是object,想要使用对象特有属性时,需要强制类型转换
* 使用泛型 : 集合中只能保存单一类型的数据
* 优点 : 由于保存数据类型一致,所以使用的时候不需要向下转型
* 缺点: 在集合中只能保存单一数据类型
* 泛型: 只能写引用类型,不能写基本类型,如果要保存数组,应该写Integer类型
3.2使用方式
package Generic;
import java.util.ArrayList;
public class Generic_01 {
public static void main(String[] args) {
//没有使用泛型可以添加任何数据类型
List list=new ArrayList();
list.add("张三");
list.add(123);
list.add('a');
//取出数据是,必须是object类型
for (Object object : list) {
}
//使用泛型
List<String> list2=new ArrayList<String>();
list2.add("123");
list2.add("asd");
list2.add("阿萨德");
//取出数据是不需要类型转换
for (String string : list2) {
System.out.println(string);
}
//String默认按照ASCII码排序,需求是按照对应的数值大小升序
TreeMap<String, Integer>map =new TreeMap<String , Integer>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.parseInt(o1)-Integer.parseInt(o2);
}
});
map.put("11", 5);
map.put("2", 2);
map.put("1", 3);
map.put("10", 7);
map.put("3", 8);
System.out.println(map);
}
}
3.3.自定义泛型
3.4 使用方式
package Generic;
public class Generic_02 {
public static void main(String[] args) {
Abc a1=new Abc();
a1.m1(1);
a1.m1("ads");
Abc<String>test2=new Abc<String>();
test2.m1("vbba");
}
}
//如果设置泛型后,不传入数据类型,则默认为object类型
class Abc<T>{
public void m1(T obj) {
System.out.println(obj);
}
}