1Set
1.1 HashSet 使用
HashSet set = new HashSet();
set.add(1);
set.add("sda");
set.remove("sda");
System.out.println(set.size());
set.isEmpty();
for(Object object: set){
}
2散列表
散列表结构 : 可以理解为 数组中保存的是链表的首节点,用来保存k和v键值对操作
hash 算法: 是一种安全的加密机制,可以把不定长的数据转换为定长数据,并且不能保证其唯一性,又叫做哈希冲突
在 java中 指的就是 hashCode方法
对一个对象生成多次hash值,值一定相同,多个对象也可能生成相同的hash值,叫哈希冲突
k 不可重复, v可以重复
添加过程:
1 根据要添加的key,调用它的 hashCode方法 生成 hash值
2 通过一定的算法,根据hash值生成数组的下标
3 判断下标中,是否有数据,如果没有数据就把该键值对映关系保存到数组中
4 如果该下标中,有数据,则调用key 的equals 方法,和对应的所有数据进行比较,如果不想等,则添加到链表尾部即可
5 如果对应的链表中,通过equals方法比较的时候,发现了相同的数据,那么key不在添加,但是value值会替代原来的value值
所以,当调用该对象的 hashCode 和equals ,所以在保存自定义类类型的时候,要注意方法覆写
在1.8 中 有个新改动,为了提高查询效率,引入了红黑树 和扩容的优化
数组默认初始化容量为16
在java中 没有散列表的概念,把散列表封装为了HashMap 和HashTable
3 Map
3.1 概述
Map 是无序的,并且保存的是 K-V键值对 映射关系,其中K不能重复,V可以重复
HashMap:底层是散列表
TreeMap: 底层是红黑树,元素必须按照一定的规则进行排序
映射关系: 如 商品和购买数量 或者数据统计
"sadsdsadscxcg"统计每个字符出现的个数,使用HashMap进行存储,字符做K,次数做V
3.2继承体系
3.3HashMap
public static void main(String[] args){
//创建map
HashMap map = new HashMap();
//添加K -V
map.put("A", "one");
map.put("B", "two");
map.put("C", "three");
map.put(65, 200);
map.put('A', "11111");
//Key 重复不添加 value替换
map.put("A", "22222");
//支持K和V都 null 但是 没意义
map.put(null, null);
//个数
System.out.println(map.size());
// get 根据K 获取V的值
System.out.println(map.get("B"));
//判断是否包含某个value
System.out.println(map.containsKey("two"));
//根据key 删除 该映射关系, 返回对应的 value 值
map.remove(65);
//获取所有的value 并放回到集合中返回
Collection values = map.values();
for(Object object :values){
System.out.println(object);
}
System.out.println("++++++");
//keySet: 获取所有的key 封装到set对象中并返回
Set keys = map.keySet();
for(Object object:keys){
System.out.println(object +" ."+ map.get(object) );
}
System.out.println("++++++");
//把map 转换为set
//Entry类中,保存了K 和V俩个遍历 ,把map中的k和V转换为entry类中的对象进行存储,所以我们只需要保存entry对象,就等于保存了k v
Set set = map.entrySet();
for(Object object : set){
System.out.println(object);
//转换为entry类型
Entry entry = (Entry) object;
//获取k 和V
System.out.println(entry.getKey()+",,,,." + entry.getValue());
}
}
3.4TreeMap
保存的元素会按照一定的规划进行排序,底层是红黑树,Comaparable 和 Comparator
public static void main(String[] args){
//添加自定义类型,并且Product中实现了Comparable接口
TreeMap map = new TreeMap();
map.put(new Product("苹果",5.2), 10);
map.put(new Product("香蕉",5.5), 10);
System.out.println(map.size());
//添加已有类型,且该类型实现了Comparable接口,Integer默认升序
//如果该类型没有实现Comparable 接口,或我们想要降序 则需要使用Comparator
map = new TreeMap(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer)02;
return i2-i1;
}
});
map.put(1, "a");
map.put(21, "a");
map.put(2, "a");
map.put(3, "a");
System.out.println(map.size());
System.out.println(map);
}
}
class Product implements Comparable{
private String name;
private double price;
public Product(String name, double price) {
super();
this.name = name;
this.price = price;
}
@Override
public int compareTo(Object o) {
if(o instanceof Product){
Product p = (Product) o;
if(this.price > p.price){
return 1;
}else if(this.price < p.price){
return -1;
}
}
return 0;
}
4泛型
在编译过程中检测数据类型是否匹配,必须是引用类型,不能使用基本类型
优点: 统一了数据类型,减少了类型转换
缺点:只能保存同一种类型
4.1使用方式
public static void main(String[] args){
//没有使用泛型
List list = new ArrayList();
// 放什么都可以
list.add(new A());
list.add(1);
//取的时候,拿到的是Object
for(Object object :list){
//使用需要进行判断和向下转型才行
if(object instanceof A){
A a = (A)object;
a.m1();
}
}
//使用泛型, 规定该集合中 只能保存A类型
List<A> list2 = new ArrayList<A>();
list2.add(new A());
//添加其他的 会报错 并且是编译报错
// list2.add(111);
//使用的时候,拿到的就直接是 A类型,不会出现类型转换的异常
// 因为只要能运行,里面一定是A
for(A a:list2){
a.m1();
}
}
}
class A{
public void m1(){
System.out.println("执行m1");
}
}
4.2 例题
Map 是以Value 进行排序
* Map 是没有办法按照value排序的,因为源码中写死了,使用key进行比较
* 所以 只能保存到List中进行排序
public static void main(String[] args){
Map<String,Integer> map =new TreeMap<String,Integer>();
map.put("a", 11);
map.put("a", 212);
map.put("c", 111);
map.put("b", 1);
map.put("d", 2);
System.out.println(map);
//把Map封装到entry中并保存到set中
Set set =map.entrySet();
//把Set保存到list中,通过ArrayList的有参构造可以直接把set转换为list
List<Entry<String,Integer>> list = new ArrayList<Entry<String,Integer>>(set);
//排序
Collections.sort(list,new Comparator<Entry<String,Integer>>(){
@Override
public int compare(Entry<String, Integer> o1,
Entry<String, Integer> o2) {
return o1.getValue()-o2.getValue();
}
});
System.out.println(list);
}