--Map接口简介
今天来看一看map集合,map映射接口,用于存放键值对,,通过key来查找value,顾名思义key不能为空,唯一且不重复,不然底层怎么查呢!
可以从图中看出Map为单独的接口,他和Collection有什么区别呢?
Map和Collection在集合中并列存在。
Map集合是双列的,键值对,而Collection是单列集合
Map存储元素使用put方法,Collection使用Put方法。
Map遍历没有直接取出元素的方法,而是先转成Set集合,再通过迭代获取元素。
--Map常用方法
--Map应用
添加:使用HashMap。立了学生姓名和年龄之间的映射关系。并试图添加重复的键
public static voidmain(String[] args) {//定义一个Map的容器对象
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);//map1.put("jack", 30); 在没有hashCode和equals方式 添加重复的键值(值不同),会覆盖掉前面key值相同的值
System.out.println(map1);
Map map2 = new HashMap();
map2.put("张三丰", 100);
map2.put("虚竹", 20);
System.out.println("map2:" +map2);//从指定映射中将所有映射关系复制到此映射中。
map1.putAll(map2);
System.out.println("map1:" +map1);
}
删除:
public static voidmain(String[] args) {//删除://remove() 删除关联对象,指定key对象//clear() 清空集合对象
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);
System.out.println(map1);//指定key,返回删除的键值对映射的值。
map1.remove("java");
System.out.println(map1);
map1.clear();
System.out.println("map1:" +map1);
}
获取:
public static voidmain(String[] args) {//获取://V get(Object key) 通过指定的key对象获取value对象//int size() 获取容器的大小
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);
System.out.println(map1);//V get(Object key) 通过指定的key对象获取value对象
System.out.println("value:" + map1.get("jack"));//int size() 获取容器的大小
System.out.println("map.size:" +map1.size());
}
判断:
public static voidmain(String[] args) {//判断://boolean isEmpty() 判断集合是否为空 长度为0返回true否则false//boolean containsKey(Object key) 判断集合中是否包含指定的key//boolean containsValue(Object value)
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);
System.out.println(map1);
System.out.println("isEmpty:" +map1.isEmpty());
System.out.println("containskey:" + map1.containsKey("jack"));
System.out.println("containsvalues:" + map1.containsValue(100));
}
遍历Map的4中方式:
第一种:
public static voidmain(String[] args) {//遍历Map 第一种方式
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);//通过 map1.keySet() 获取key 通过key 找到value
for(String key : map1.keySet()) {
Integer value=map1.get(key);
System.out.println("key : "+key+" value : "+value);
}
}
第二种:
public static voidmain(String[] args) {//遍历Map 第二种方式
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);//通过Map.Entry(String,Integer) 获取,然后使用entry.getKey()获取到键,通过entry.getValue()获取到值
for(Map.Entryentry : map1.entrySet()){
System.out.println("键 key :"+entry.getKey()+" 值value :"+entry.getValue());
}
}
第三种:
//遍历Map 第三种方式
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);//第三种只遍历键或者值,通过加强for循环
for(String s1:map1.keySet()){//遍历map的键
System.out.println("键key :"+s1);
}for(Integer s2:map1.values()){//遍历map的值
System.out.println("值value :"+s2);
}
System.out.println("====================================");
}
第四种:
public static voidmain(String[] args) {//遍历Map 第一种方式
Map map1 = new HashMap();
map1.put("jack", 20);
map1.put("rose", 18);
map1.put("lucy", 17);
map1.put("java", 25);//第四种Iterator遍历获取,然后获取到Map.Entry,再得到getKey()和getValue()
Iterator> it=map1.entrySet().iterator();while(it.hasNext()){
Map.Entry entry=it.next();
System.out.println("键key :"+entry.getKey()+" value :"+entry.getValue());
}
}
HashMap
底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。要保证键的唯一性,需要覆盖hashCode方法,和equals方法。
案例:自定义对象作为Map的键。
public classDemo3 {public static voidmain(String[] args) {
HashMap hm = new HashMap();
hm.put(new Person("jack", 20), "1001");
hm.put(new Person("rose", 18), "1002");
hm.put(new Person("lucy", 19), "1003");
hm.put(new Person("hmm", 17), "1004");
hm.put(new Person("ll", 25), "1005");
System.out.println(hm);
System.out.println(hm.put(new Person("rose", 18), "1006")); //重写hashCode和equalse后key相同不会覆盖
Set> entrySet =hm.entrySet();
Iterator> it =entrySet.iterator();while(it.hasNext()) {
Entry next =it.next();
Person key=next.getKey();
String value=next.getValue();
System.out.println(key+ " = " +value);
}
}
}classPerson {privateString name;private intage;
Person() {
}public Person(String name, intage) {this.name =name;this.age =age;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}
@Overridepublic inthashCode() {return this.name.hashCode() + age * 37;
}
@Overridepublic booleanequals(Object obj) {if (obj instanceofPerson) {
Person p=(Person) obj;return this.name.equals(p.name) && this.age ==p.age;
}else{return false;
}
}
@OverridepublicString toString() {return "Person@name:" + this.name + " age:" + this.age;
}
}
}
TreeMap
TreeMap的排序,TreeMap可以对集合中的键进行排序。如何实现键的排序?
方式一:元素自身具备比较性
和TreeSet一样原理,需要让存储在键位置的对象实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做 元素的自然排序也叫做默认排序。
方式二:容器具备比较性
当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重 写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。
注意:当Comparable比较方式和Comparator比较方式同时存在时,以Comparator的比较方式为主;
注意:在重写compareTo或者compare方法时,必须要明确比较的主要条件相等时要比较次要条件。(假设姓名和年龄一致的人为相同的人, 如果想要对人按照年龄的大小来排序,如果年龄相同的人,需要如何处理?不能直接return 0,以为可能姓名不同(年龄相同姓名不同的人 是不同的人)。此时就需要进行次要条件判断(需要判断姓名),只有姓名和年龄同时相等的才可以返回0.)
通过return 0来判断唯一性。
public class Demo4 {
public static void main(String[] args) {
TreeMap tree = new TreeMap();
tree.put("张三", 19);
tree.put("李四", 20);
tree.put("王五", 21);
tree.put("赵六", 22);
tree.put("周七", 23);
tree.put("张三", 24);
System.out.println(tree);
System.out.println("张三".compareTo("李四"));//-2094
}
}
自定义元素排序
public classDemo3 {public static voidmain(String[] args) {
TreeMap hm = new TreeMap(newMyComparator());
hm.put(new Person("jack", 20), "1001");
hm.put(new Person("rose", 18), "1002");
hm.put(new Person("lucy", 19), "1003");
hm.put(new Person("hmm", 17), "1004");
hm.put(new Person("ll", 25), "1005");
System.out.println(hm);
System.out.println(hm.put(new Person("rose", 18), "1006"));
Set> entrySet =hm.entrySet();
Iterator> it =entrySet.iterator();while(it.hasNext()) {
Entry next =it.next();
Person key=next.getKey();
String value=next.getValue();
System.out.println(key+ " = " +value);
}
}
}class MyComparator implements Comparator{
@Overridepublic intcompare(Person p1, Person p2) {if (p1.getAge() >p2.getAge()) {return -1;
}else if (p1.getAge()
}returnp1.getName().compareTo(p2.getName());
}
}class Person implements Comparable{privateString name;private intage;
Person() {
}public Person(String name, intage) {this.name =name;this.age =age;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}
@Overridepublic inthashCode() {return this.name.hashCode() + age * 37;
}
@Overridepublic booleanequals(Object obj) {if (obj instanceofPerson) {
Person p=(Person) obj;return this.name.equals(p.name) && this.age ==p.age;
}else{return false;
}
}
@OverridepublicString toString() {return "Person@name:" + this.name + " age:" + this.age;
}
@Overridepublic intcompareTo(Person p) {if (this.age >p.age) {return 1;
}else if (this.age
}return this.name.compareTo(p.name);
}
}
注意:Set的元素不可重复,Map的键不可重复,如果存入重复元素如何处理
Set元素重复元素不能存入add方法返回false
Map的重复健将覆盖旧键,将旧值返回。