java集合之HashMap
Map接口详解
映射(map)是一个存储键/值对的对象。给定一个键,可查询得到它的值,键和值都是对象
键必须是唯一的,值可以重复
有些映射可以接收null键和null值,而有的不行
支持映射的接口:Map,SortedMap(按关键字升序保存)
Map接口定义的方法:
int size()
boolean isEmpty()
boolean containsKey(Object key)
boolean containsValue(Object value)
V get(Object key)
V put(K key,V value)//返回旧值
V remove(Object key)
Collection<V> values()
Set<Map.Entry<K,V>> entrySet()
Map.Entry是映射项(键-值对)类型
Map.Entry方法:
K getKey()
V getValue()
V setValue(V value)
HashMap
HashMap类是基于哈希表的map接口的实现,并允许使用null键和null值,默认容量16
构造方法:
HashMap()
HashMap(Map m)
HashMap(int capacity)
HashMap(int capacity,float fillRato)//fillRato为填充因子,默认0.75
HashMap实现Map接口并扩展AbstractMap,本身并没有增加任何新的方法
散列不保证它的元素的顺序,元素加入散列映射的顺序并不一定是它们被迭代读出的顺序
数组位置计算步骤:
int hashCode = key.hashCode();//哈希码
int hash = hash(hashCode);//散列运算,得到散列值
int i=indexFor(hash,table.length);//算出下标值
不同的key有可能算出来相同的散列值,算出来的下标一样,就冲突了,新的数据会放在下标位置,旧的会放在新数据的next对象中。
哈希码的产生和使用
当调用对象的hashCode()方法时就会返回当前对象的哈希码值。支持此方法是为了提高哈希表的性能。
hashCode常规协定:
在Java应用程序执行期间,在对同一对象多次调用hashCode()方法时,必须一致地返回相同的整数,前提是将对象进行equals比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据equals()方法【未被重写的equals方法】,两个对象是相等的,那么对这两个对象中的每个对象调用hashCode()方法都必须生成相同的整数。
如果根据equals()方法,两个对象不相等,那么对这两个中的任一对象上调用hashCode()方法不要求一定生成不同的整数。但是,一般为不相等的对象生成不同整数结果可以提高哈希表的性能。
demo:
package pkg1.HashMap; import java.util.Collection; import java.util.HashMap; import java.util.Map.Entry; import java.util.Set; public class HashMapDemo { public static void main(String[] args) { test1(); test2(); } public static void test1() { HashMap<String,String> map=new HashMap<String, String>(); map.put("jay", "张三"); map.put("marry", "小红"); map.put("rose", "卢斯"); System.out.println(map); //获取Map中所有键 Set<String> keys = map.keySet();//光标放在方法上,ctrl+1自动补全返回类型 System.out.println("根据keySet()输出key和value:"); for(String key:keys){ System.out.print(key +" "+map.get(key)+" "); } ////获取所有值 //Collection<String> values = map.values(); System.out.println("size():"+map.size()); //获取所有数据 Set<Entry<String, String>> entrySet = map.entrySet(); System.out.println("根据entrySet()输出key和value:"); for(Entry<String, String> kv:entrySet){ if(kv.getKey()=="rose") kv.setValue("小卢斯");//替换值 System.out.print(kv.getKey() +"-"+kv.getValue()+" "); } map.clear();//清空 System.out.println("---------------------"); } public static void test2() { HashMap<Student, String> map=new HashMap<Student, String>(); map.put(new Student("zs", 10),"张三"); map.put(new Student("ls", 16),"李四"); map.put(new Student("rs", 20),"卢斯"); map.put(new Student("zs", 10),"小张三"); System.out.println(map.size()); Set<Entry<Student, String>> entrySet = map.entrySet(); for(Entry<Student, String> kv:entrySet){ System.out.print(kv.getKey().toString() +"-"+kv.getValue()+" "); } } } class Student{ private String name; private int age; public Student(String name, int age) { super(); 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; } //重写 hashCode()和equals()方法,HashMap中处理才会当成同一对象 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } public String toString(){ return name+" "+age; } }
效果: