Map集合是一种映射集合,Map集合中存在一种对应关系key--value键值对 要求: 1.key的值必须是唯一的不能重复 2.value可以重复不唯一 1个key只能对应一个value,但是同一个value可以对应多个key HashMap 子类: LinkedHashMap:双向链表、没有特殊方法 TreeMap:底层是红黑二叉树实现,默认提供对key从小到大排序 HashTable和HashMap都是Map的实现类,HashTable是线程安全,效率低。HashMap是线程不安全,效率高 propreties:资源文件-->加载
Map集合方法演示
/*
HashMap常用方法
*/
public class HashMapDome {
public static void main(String[] args){
//创建Map对象
Map map = new HashMap();
//向map集合对象存储map集合中的元素
Map map1 = new HashMap<>(map);
//1向集合中添加元素,put方法有返回值返回值为Value
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
map.put("key4","value4");
map.put("key5","value5");
System.out.println(map);
//2向集合中添加集合(添加集合中的元素)
map1.putAll(map);
System.out.println(map1);
//3清空集合、、清空集合但是集合还在
map1.clear();
System.out.println(map1);
//4判断集合中是否存在指定key
boolean res = map.containsKey("key7");
System.out.println(res);
//5判断集合中是否存在指定的value值
boolean rea = map.containsValue("value7");
System.out.println(rea);
//6通过key获取value值,若key不存在返回null
String value = map.get("key4");
System.out.println(value);
//7判断集合是否为空
System.out.println(map1.isEmpty());
//8key相当于存储带了set集合中排重 保持唯一
//获取所有的key值并存储到set中
Set set = map.keySet();
//此时所有的key值都存储到了set集合中,就可以通过操作set集合
//就能获取或改变map集合对应的键值对
for (String keys : set) {
if (keys.equals("key6")){
map.put(keys,"value10");
}
}System.out.println(map);
//9获取Map中所有value值,存储到Collection集合中
Collection c = map.values();
for (String value1 : c) {
System.out.println(value1);
}
//10获取所有键值对的个数总和
System.out.println(map.size());
//11删除,通过key删除对应的键值对,返回值是对应的value
//删除成功返回相应的value值,失败返回false
String value2=map.remove("key6");
System.out.println(value2);
// 通过此方法可以得到有个Set集合,需要给set集合添加泛型,这个方法的类型是一个Map.Entry
// Map.Entry自己也要泛型,这个泛型类型需要map集合中存储的key和value的数据累心一致
Set> entry = map.entrySet();
System.out.println(entry);
for (Map.Entry stringStringEntry : entry) {
System.out.println(stringStringEntry.getKey()+" "+stringStringEntry.getValue());
}
//若存在两个相同的key值,最后一次添加的键值对,会替代第一次添加的键值对
map1.put("123","4560");
map1.put("123","450");
map1.put("123","456");
System.out.println(map1);
}
}
泛型(genericity):
为什么要使用泛型?
案例1:
集合可以存储任何数据类型,必然集合中需要使用Object类型接受
1.若需要使用计算或是当前对象的特有属性和方法强制类型转换(向下转型)
2.向集合中存储元素,无法限制存储元素的数据类型
我们可以使用泛型来约束集合中存储的数据类型,并且使用了泛型后就不需要强制类型转换了(向下转型)
但是这样一来会出现一个问题,不能再存储任何数据类型,只能存储限制的数据类型对应的值
案例2:
设计一个点(Ponit),来封装坐标,要求坐标的数据类型可以支持String,int,double,float,
class Point{
private String x;
private String y;
}
class Point{
private int x;
private int y;
}
....
原则DRY 不要重复自己
可以通过创建对象时在决定Point的数据是什么,这样一来是不是就可以不用创建多个Point而只要建立一个类即可
class Point{
privare T x;
private T y;
}
new Point();
就可以使用泛型
什么是泛型:
1.泛型的含义就是代表任何数据类型,但是本身没有任何含义,就是一个站位符
2.在不能明确数据类型式,我们即可以使用这种占位符的形式来替代数据类型
特点:
通过<数据类型>接收一种引用数据类型,在编译程序时该类型会对[集合、类、接口、方法]中传入的数据进行类型匹配
如果不是当前类型,编译就不会通过,从运行时的问题提升到了编译时
泛型是用在编译时期的,编译完成之后产生.class文件后泛型就不会存在了-->泛型擦除
泛型在定义阶段没有任何意义,只是占位符问题
实际使用中参数的传递或类型的定义,此时当前泛型才会有真正的意义
泛型的分类
泛型应用在类上
泛型中定义的字本身没任何意义,就是占位
看Class包
泛型应用在方法上
1.泛型类中的泛型只能适用于非静态方法,如果需要给静态方法添加泛型,此时就需要定义泛型方法了
2.方法想使用自己的泛型类型,并不想使用其他方式提供的泛型,此时就需要使用泛型方法了
看Method包
泛型应用在接口上
看Inteface包
泛型通配符 ?
通配符不能单独使用,仅限于在使用参数定义数据类型时使用
? 在不知道是什么数据类型时,也可以使用? 来代替
泛型的限定:
extends 类>
此时只能传入当前类的子类或当前类
super 类>
此时只能传入当前类或父类类型
ps:
泛型擦除:
1.泛型在编译过后会被自动消除
2.当把带有泛型的集合赋值给不带有泛型的集合时,此时泛型被擦除(手动擦除)
确定泛型接口中泛型的数据类型,使用类实现接口并制定泛型类型
public class Person implements InterFaceDemo{
接口中和类是类似的使用方式
public interface InterFaceDemo{
public static void main(String[] args) {
//3.以匿名内部类的形式来完成泛型接口的创建,同时指定泛型类型
new InterFaceDemo() {
@Override
public void show(String t) {
// TODO Auto-generated method stub
}
};
}
}
泛型类实现泛型接口,此时可以通过泛型类型中的泛型来占位泛型接口中的泛型
创建当前泛型类对象的时,此时就可以制定泛型的数据类型
public class Student implements InterFaceDemo{
public void show(M t) {
}}