Java集合主要由2大体系构成,分别是Collection体系和Map体系,其中Collection和Map分别是2大体系中的顶层接口。
今天主要讲:Map主要有二个子接口,分别为HashMap、TreeMap。
继承关系图:
Map的整体特点:
1. 键值对存放<key , value>
2. 遍历需要使用迭代器:Iterator
常用Map HashMap
import java.util.HashMap; import java.util.Map; public class var { public static void main(String[] agrs){ // 定义一个Map的容器对象 Map<String, Integer > map1 = new HashMap<String, Integer >(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); System.out.println(map1); map1.put("jack", 30); //在没有hashCode和equals方式 添加重复的键值(值不同),会覆盖掉前面key值相同的值 System.out.println(map1); Map<String, Integer> map2 = new HashMap<String, Integer>(); map2.put("张三丰", 100); map2.put("虚竹", 20); System.out.println("map2:" + map2); // 从指定映射中将所有映射关系复制到此映射中。 map1.putAll(map2); System.out.println("map1:" + map1); // 指定key,返回删除的键值对映射的值。 map1.remove("java"); System.out.println(map1); // V get(Object key) 通过指定的key对象获取value对象 System.out.println("value:" + map1.get("jack")); // boolean isEmpty() 判断集合是否为空 长度为0返回true否则false // boolean containsKey(Object key) 判断集合中是否包含指定的key // boolean containsValue(Object value) System.out.println("isEmpty:" + map1.isEmpty()); System.out.println("containskey:" + map1.containsKey("jack")); System.out.println("containsvalues:" + map1.containsValue(100)); } }
运行结果:
Map 的四种遍历方式
import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class var { public static void main(String[] agrs){ // 定义一个Map的容器对象 Map<String, Integer > map1 = new HashMap<String, Integer >(); map1.put("jack", 20); map1.put("rose", 18); map1.put("lucy", 17); map1.put("java", 25); System.out.println("第一种:"); //通过 map1.keySet() 获取key 通过key 找到value for (String key : map1.keySet()) { Integer value = map1.get(key); System.out.print("【key:"+key+" value:"+value+"】; "); } System.out.println(); System.out.println("第二种:"); //通过Map.Entry(String,Integer) 获取,然后使用entry.getKey()获取到键,通过entry.getValue()获取到值 for(Map.Entry<String, Integer> entry : map1.entrySet()){ System.out.print("【key:"+entry.getKey()+"value:"+entry.getValue()+"】; "); } System.out.println(); System.out.println("第三种:"); //第三种只遍历键或者值,通过加强for循环 for(String s1:map1.keySet()){//遍历map的键 System.out.print("键key:"+s1+"; "); } System.out.println(); for(Integer s2:map1.values()){//遍历map的值 System.out.print("值value:"+s2+"; "); } System.out.println(); System.out.println("第四种:"); //第四种Iterator遍历获取,然后获取到Map.Entry<String, String>,再得到getKey()和getValue() Iterator<Map.Entry<String, Integer>> it=map1.entrySet().iterator(); while(it.hasNext()){ Map.Entry<String, Integer> entry=it.next(); System.out.print("【key:"+entry.getKey()+" value:"+entry.getValue()+"】; "); } System.out.println(); } }
运行结果:
HashMap 底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。要保证键的唯一性,需要覆盖hashCode方法,和equals方法。
案例:
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int hashCode() { return this.name.hashCode() + age * 37; } @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person p = (Person) obj; return this.name.equals(p.name) && this.age == p.age; } else { return false; } } @Override public String toString() { return "Person@name:" + this.name + " age:" + this.age; } }
import java.util.HashMap; public class var { public static void main(String[] agrs){ HashMap<Person, String> hm = new HashMap<Person, String>(); 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); hm.put(new Person("rose", 18), "1006"); System.out.println(hm); //重写hashCode和equalse后key就相同了。value值更新 } }
运行结果:
常用Map:TreeMap
特点:元素具有比较性,支持排序。
import java.util.TreeMap; public class var { public static void main(String[] agrs){ TreeMap<String, Integer> tree = new TreeMap<String, Integer>(); 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 class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int hashCode() { return this.name.hashCode() + age * 37; } @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person p = (Person) obj; return this.name.equals(p.name) && this.age == p.age; } else { return false; } } @Override public String toString() { return "Person@name:" + this.name + " age:" + this.age; } @Override public int compareTo(Person p) { if (this.age > p.age) { return 1; } else if (this.age < p.age) { return -1; } return this.name.compareTo(p.name); } }
import java.util.Comparator; public class MyComparator implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { if (p1.getAge() > p2.getAge()) { return -1; } else if (p1.getAge() < p2.getAge()) { return 1; } return p1.getName().compareTo(p2.getName()); } }
public class var { public static void main(String[] agrs){ TreeMap<Person, String> hm = new TreeMap<Person, String>( new MyComparator()); 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); } }
运行结果:
注意:Set的元素不可重复,Map的键不可重复,如果存入重复元素如何处理
Set元素重复元素不能存入add方法返回false
Map的重复健将覆盖旧键,将旧值返回。
其他Map详情见JDK API。