zoukankan      html  css  js  c++  java
  • Map集合

    Map集合为映射类型,映射与集和列表有明显的区别,映射中的每个对象都是成对存在的。映射中存储的每个对象都有一个相应的键(Key)对象,在检索对象时必须通过相应的键对象来获取值(value)对象,类似于在字典中查找单词一样,因此要求键对象必须是惟一的。键对象还决定了存储对象在映射中的存储位置,但并不是键对象本身决定的,需要通过一种散列技术进行处理,从而产生一个被称作散列码的整数值,散列码通常用作一个偏置量,该偏置量是相对于分配给映射的内存区域的起始位置的,由此来确定存储对象在映射中的存储位置。理想情况下,通过散列技术得到的散列码应该是在给定范围内均匀分布的整数值,并且每个键对象都应该得到不同的散列码。 (1)Map集合的用法 Map集合包括Map接口以及Map接口的所有实现类。由Map接口提供用来操作集合的常用方法如下表5所示:

    Map接口的常用实现类有HashMap和TreeMap,HashMap类通过哈希码对其内部的映射关系进行快速查找,而TreeMap类中的映射关系存在一定的顺序,如果希望在遍历集合时是有序的,应该使用由TreeMap类实现的Map集合,否则建议使用由HashMap类实现的Map集合,因为由HashMap类实现的Map集合对于添加和删除映射关系更高效。 Map集合允许值对象为null,并且没有个数限制,因此当get()方法的返回值为null时,可能有两种情况,一种是在集合中没有该键对象,另一种是该键对象没有映射任何值对象,即值对象为null。因此,在Map集合中不应该利用get()方法来判断是否存在某个键,而应该利用containsKey()方法来判断。 例如: 源文件:TestMap.java

    1. import java.util.*;  
    2. public class TestMap{  
    3.     public static void main(String args[]){  
    4.         Map<Integer,String> map = new HashMap<Integer,String>();  
    5.         System.out.println("map集合是否为空:"+map.isEmpty());  
    6.         map.put(22015,null);  
    7.         System.out.println("map集合是否为空:"+map.isEmpty());  
    8.         map.put(22016,"马先生");  
    9.         System.out.println("map集合是否为空:"+map.isEmpty());  
    10.           
    11.         System.out.println("get()方法的返回结果:");  
    12.         System.out.print(map.get(22015));  
    13.         System.out.print("  "+map.get(22016));  
    14.         System.out.println("    "+map.get(22017));  
    15.   
    16.         System.out.println("containsKey()方法的返回结果:");  
    17.         System.out.print(map.containsKey(22015));  
    18.         System.out.print("  "+map.containsKey(22016));  
    19.         System.out.println("    "+map.containsKey(22017));  
    20.   
    21.         System.out.println("map集合中映射的个数:"+map.size());  
    22.         map.remove(22015);  
    23.         System.out.println("map集合中映射的个数:"+map.size());  
    24.     }  
    25. }  
    import java.util.*;
    public class TestMap{
    	public static void main(String args[]){
    		Map<Integer,String> map = new HashMap<Integer,String>();
    		System.out.println("map集合是否为空:"+map.isEmpty());
    		map.put(22015,null);
    		System.out.println("map集合是否为空:"+map.isEmpty());
    		map.put(22016,"马先生");
    		System.out.println("map集合是否为空:"+map.isEmpty());
    		
    		System.out.println("get()方法的返回结果:");
    		System.out.print(map.get(22015));
    		System.out.print("	"+map.get(22016));
    		System.out.println("	"+map.get(22017));
    
    		System.out.println("containsKey()方法的返回结果:");
    		System.out.print(map.containsKey(22015));
    		System.out.print("	"+map.containsKey(22016));
    		System.out.println("	"+map.containsKey(22017));
    
    		System.out.println("map集合中映射的个数:"+map.size());
    		map.remove(22015);
    		System.out.println("map集合中映射的个数:"+map.size());
    	}
    }
    

    程序的运行结果如下: map集合是否为空:true map集合是否为空:false map集合是否为空:false get()方法的返回结果: null    马先生  null containsKey()方法的返回结果: true    true    false map集合中映射的个数:2 map集合中映射的个数:1
    (2)使用HashMap类 HashMap类实现了Map接口,由HashMap类实现的Map集合允许以null作为键对象,但是因为键对象不可以重复,所以这样的键对象只能有一个。如果经常需要添加、删除和定位映射关系,建议利用HashMap类实现Map集合,不过在遍历集合时得到的映射关系是无序的。 在使用由HashMap类实现的Map集合时,如果想有效地使用,就必须重写作为主键对象类的hashCode()方法,在重写hashCode()方法时,有两条基本原则: ● 不唯一原则:不必为每个对象生成一个惟一的哈希码,只要通过hashCode()方法生成的哈希码,利用get()方法能够得到利用put()方法添加的映射关系即可。 ● 分散原则:生成哈希码的算法应尽量使哈希码的值分散一些,不要将很多哈希码值都集中在一个范围内,这样有利于提高由HashMap类实现的Map集合的性能。 例如: 源文件:PK_person.java

    1. public class PK_person{  
    2.     private String prefix;  
    3.     private long number;  
    4.     public String setPrefix(){  
    5.         return prefix;  
    6.     }  
    7.     public void setPrefix(String prefix){  
    8.         this.prefix = prefix;  
    9.     }  
    10.     public long getNumber(){  
    11.         return number;  
    12.     }  
    13.     public void setNumber(long number){  
    14.         this.number = number;  
    15.     }  
    16.     public String getPK(){  
    17.         return this.prefix+"_"+this.number;  
    18.     }  
    19.     public void setPK(String pk){  
    20.         int i = pk.indexOf("_");  
    21.         this.prefix = pk.substring(0,i);  
    22.         this.number = new Integer(pk.substring(i));  
    23.     }  
    24. }  
    public class PK_person{
    	private String prefix;
    	private long number;
    	public String setPrefix(){
    		return prefix;
    	}
    	public void setPrefix(String prefix){
    		this.prefix = prefix;
    	}
    	public long getNumber(){
    		return number;
    	}
    	public void setNumber(long number){
    		this.number = number;
    	}
    	public String getPK(){
    		return this.prefix+"_"+this.number;
    	}
    	public void setPK(String pk){
    		int i = pk.indexOf("_");
    		this.prefix = pk.substring(0,i);
    		this.number = new Integer(pk.substring(i));
    	}
    }
    

    源文件:Person.java

    1. public class Person{  
    2.     private String name;  
    3.     private PK_person number;  
    4.     public Person(PK_person number,String name){  
    5.         this.number = number;  
    6.         this.name = name;  
    7.     }  
    8.     public String getName(){  
    9.         return name;  
    10.     }  
    11.     public void setName(String name){  
    12.         this.name = name;  
    13.     }  
    14.     public PK_person getNumber(){  
    15.         return number;  
    16.     }  
    17.     public void setNumber(PK_person number){  
    18.         this.number = number;  
    19.     }  
    20. }  
    public class Person{
    	private String name;
    	private PK_person number;
    	public Person(PK_person number,String name){
    		this.number = number;
    		this.name = name;
    	}
    	public String getName(){
    		return name;
    	}
    	public void setName(String name){
    		this.name = name;
    	}
    	public PK_person getNumber(){
    		return number;
    	}
    	public void setNumber(PK_person number){
    		this.number = number;
    	}
    }
    

    源文件:TestMap.java

    1. import java.util.*;  
    2. public class TestMap{  
    3.     public static void main(String args[]){  
    4.         Map<PK_person,Person> map = new HashMap<PK_person,Person>();  
    5.         PK_person pk_person1 = new PK_person();  
    6.         pk_person1.setPrefix("MR");  
    7.         pk_person1.setNumber(22015);  
    8.         map.put(pk_person1,new Person(pk_person1,"马先生"));  
    9.         PK_person pk_person2 = new PK_person();  
    10.         pk_person2.setPrefix("MR");  
    11.         pk_person2.setNumber(22015);  
    12.         Person person = map.get(pk_person2);  
    13.         if(person == null){  
    14.             System.out.println("该键对象不存在!");  
    15.         }  
    16.         else{  
    17.             System.out.println(person.getNumber().getNumber()+" "+person.getName());  
    18.         }  
    19.     }  
    20. }  
    import java.util.*;
    public class TestMap{
    	public static void main(String args[]){
    		Map<PK_person,Person> map = new HashMap<PK_person,Person>();
    		PK_person pk_person1 = new PK_person();
    		pk_person1.setPrefix("MR");
    		pk_person1.setNumber(22015);
    		map.put(pk_person1,new Person(pk_person1,"马先生"));
    		PK_person pk_person2 = new PK_person();
    		pk_person2.setPrefix("MR");
    		pk_person2.setNumber(22015);
    		Person person = map.get(pk_person2);
    		if(person == null){
    			System.out.println("该键对象不存在!");
    		}
    		else{
    			System.out.println(person.getNumber().getNumber()+"	"+person.getName());
    		}
    	}
    }
    

    程序的运行结果如下: 该键对象不存在! 无论执行多少次,输出的信息都为“该键对象不存在!”,即在集合中不存在该键对象。这是因为没有重写java.lang.Object()类中的hashCode()和equals()方法,equals()方法默认比较两个对象的地址,因此即使这两个键对象的内容完全相同,也不认为是同一个对象,重写后的hashCode()和equals()方法的完整代码如下:

    1. public int hashCode(){//重写hashCode()方法  
    2.     return (int)(number + prefix.hashCode());  
    3. }  
    4. public boolean equals(Object obj){//重写equals()方法  
    5.     if(obj == null){  
    6.         return false;  
    7.     }  
    8.     if(getClass()!=obj.getClass()){  
    9.         return false;  
    10.     }  
    11.     if(this == obj){  
    12.         return true;  
    13.     }  
    14.     final PK_person other = (PK_person)obj;  
    15.     if(this.hashCode()!=other.hashCode()){  
    16.         return false;  
    17.     }  
    18.     return true;  
    19. }  
    public int hashCode(){//重写hashCode()方法
    	return (int)(number + prefix.hashCode());
    }
    public boolean equals(Object obj){//重写equals()方法
    	if(obj == null){
    		return false;
    	}
    	if(getClass()!=obj.getClass()){
    		return false;
    	}
    	if(this == obj){
    		return true;
    	}
    	final PK_person other = (PK_person)obj;
    	if(this.hashCode()!=other.hashCode()){
    		return false;
    	}
    	return true;
    }
    

    重写PK_person类中的hashCode()和equals()方法后,再次执行程序,结果如下: 2015   马先生
    (3)使用TreeMap类 TreeMap类不仅实现了Map接口,还实现了Map接口的子接口java.util.SortedMap。由TreeMap类实现的Map集合不允许键对象为null,因为集合中的映射关系是根据键对象按照一定顺序排列的,TreeMap类通过实现SortedMap接口得到的方法如下表6所示:

    在添加、删除和定位映射关系上,TreeMap类要比HashMap类的性能差一些,但是其中的映射关系具有一定的顺序,如果不需要一个有序的集合,则建议使用HashMap类;如果需要进行有序的遍历输出,则建议使用TreeMap类,在这种情况下,可以先使用由HashMap类实现的Map集合,在需要顺序输出时,在利用现有的HashMap类的实例创建一个具有完全相同映射关系的TreeMap类型的实例。 例如: 源文件:Person.java

    1. public class Person{  
    2.     private String name;  
    3.     private long id_card;  
    4.     public Person(String name,long id_card){  
    5.         this.id_card = id_card;  
    6.         this.name = name;  
    7.     }  
    8.     public String getName(){  
    9.         return name;  
    10.     }  
    11.     public void setName(String name){  
    12.         this.name = name;  
    13.     }  
    14.     public long getId_card(){  
    15.         return id_card;  
    16.     }  
    17.     public void setId_card(long id_card){  
    18.         this.id_card = id_card;  
    19.     }  
    20. }  
    public class Person{
    	private String name;
    	private long id_card;
    	public Person(String name,long id_card){
    		this.id_card = id_card;
    		this.name = name;
    	}
    	public String getName(){
    		return name;
    	}
    	public void setName(String name){
    		this.name = name;
    	}
    	public long getId_card(){
    		return id_card;
    	}
    	public void setId_card(long id_card){
    		this.id_card = id_card;
    	}
    }
    

    源文件:TestMap.java

    1. import java.util.*;  
    2. public class TestMap{  
    3.     public static void main(String args[]){  
    4.         Person p1 = new Person("马先生",22015);  
    5.         Person p2 = new Person("李小姐",22018);  
    6.         Person p3 = new Person("马先生",22016);  
    7.         Map<Number,Person> map = new HashMap<Number,Person>();  
    8.         map.put(22015,p1);  
    9.         map.put(22018,p2);  
    10.         map.put(22016,p3);  
    11.         System.out.println("由HashMap类实现的Map集合,无序:");  
    12.         Iterator<Number> it1 = map.keySet().iterator();  
    13.         while(it1.hasNext()){  
    14.             Person person = map.get(it1.next());  
    15.             System.out.println(person.getId_card()+"    "+person.getName());  
    16.         }  
    17.         System.out.println("由TreeMap类实现的Map集合,键对象升序:");  
    18.         TreeMap<Number,Person> treeMap1 = new TreeMap<Number,Person>();  
    19.         treeMap1.putAll(map);  
    20.         Iterator<Number> it2 = treeMap1.keySet().iterator();  
    21.         while(it2.hasNext()){  
    22.             Person person = treeMap1.get(it2.next());  
    23.             System.out.println(person.getId_card()+"    "+person.getName());  
    24.         }  
    25.         System.out.println("由TreeMap类实现的Map集合,键对象降序:");  
    26.         TreeMap<Number,Person> treeMap2 = new TreeMap<Number,Person>(Collections.reverseOrder());  
    27.         treeMap2.putAll(map);  
    28.         Iterator<Number> it3 = treeMap2.keySet().iterator();  
    29.         while(it3.hasNext()){  
    30.             Person person = treeMap2.get(it3.next());  
    31.             System.out.println(person.getId_card()+"    "+person.getName());  
    32.         }  
    33.     }  
    34. }  
    import java.util.*;
    public class TestMap{
    	public static void main(String args[]){
    		Person p1 = new Person("马先生",22015);
    		Person p2 = new Person("李小姐",22018);
    		Person p3 = new Person("马先生",22016);
    		Map<Number,Person> map = new HashMap<Number,Person>();
    		map.put(22015,p1);
    		map.put(22018,p2);
    		map.put(22016,p3);
    		System.out.println("由HashMap类实现的Map集合,无序:");
    		Iterator<Number> it1 = map.keySet().iterator();
    		while(it1.hasNext()){
    			Person person = map.get(it1.next());
    			System.out.println(person.getId_card()+"	"+person.getName());
    		}
    		System.out.println("由TreeMap类实现的Map集合,键对象升序:");
    		TreeMap<Number,Person> treeMap1 = new TreeMap<Number,Person>();
    		treeMap1.putAll(map);
    		Iterator<Number> it2 = treeMap1.keySet().iterator();
    		while(it2.hasNext()){
    			Person person = treeMap1.get(it2.next());
    			System.out.println(person.getId_card()+"	"+person.getName());
    		}
    		System.out.println("由TreeMap类实现的Map集合,键对象降序:");
    		TreeMap<Number,Person> treeMap2 = new TreeMap<Number,Person>(Collections.reverseOrder());
    		treeMap2.putAll(map);
    		Iterator<Number> it3 = treeMap2.keySet().iterator();
    		while(it3.hasNext()){
    			Person person = treeMap2.get(it3.next());
    			System.out.println(person.getId_card()+"	"+person.getName());
    		}
    	}
    }
    

    程序的运行结果如下: 由HashMap类实现的Map集合,无序: 22016   马先生 22018   李小姐 22015   马先生 由TreeMap类实现的Map集合,键对象升序: 22015   马先生 22016   马先生 22018   李小姐 由TreeMap类实现的Map集合,键对象降序: 22018   李小姐 22016   马先生 22015   马先生

  • 相关阅读:
    蓝桥杯 奇怪的比赛
    历届试题 古堡算式
    PAT 甲级 1040 Longest Symmetric String (25 分)(字符串最长对称字串,遍历)
    PAT 甲级 1039 Course List for Student (25 分)(字符串哈希,优先队列,没想到是哈希)*...
    PAT 甲级 1038 Recover the Smallest Number (30 分)(思维题,贪心)
    PAT 甲级 1037 Magic Coupon (25 分) (较简单,贪心)
    那不是Bug,是新需求
    看看C# 6.0中那些语法糖都干了些什么(上篇)
    eclipse工具的使用心得
    送给那些刚进公司工作滴童鞋
  • 原文地址:https://www.cnblogs.com/caogang/p/4379544.html
Copyright © 2011-2022 走看看