public class Map1 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
/*
V put(K k,V v)将给定key-value存入到map中
由于key不允许重复,所以使用map已有的key去存入一个新的value时
会替换原有的value,返回值是被替换的value值
*/
map.put(1, "zs");
String s = map.put(2, "zs");//添加
System.out.println("old" + s);
map.put(3, "ww");
System.out.println(map);
String string = map.put(2, "aa");//key重复,会替换掉原先的value
System.out.println(string);//替换的value值
System.out.println(map);
}
}
public class Map2 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "zs");
map.put(2, "ls");
map.put(3, "ww");
/*
V get(K k)根据给定的k,来获取相应的value
*/
Object o=map.get(1);
System.out.println(o);//zs
/*
V remove(K k)删除所给k的key-value对,返回值为对应的value
*/
String string=map.remove(3);
System.out.println(string);//ww
System.out.println(map);
}
}
map集合遍历的3中方式
public class Map3 {
public static void main(String[] args) {
/*
遍历Map的3中方式
*/
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "zs");
map.put(2, "ls");
map.put(3, "ww");
/*
1.遍历所有的key
Set<K> keySet()该方法将所有的key存入到一个Set集合后返回,相当于遍历了所有的key
*/
Set<Integer> set = map.keySet();//Set不可重复
for (Integer i : set) {
System.out.println(i);
}
/*
2.遍历每一组键值对
Map中的每一组键值对都是有Map的内部类:java.util.Map.Entry的一个实例表示
Entry有两个方法:getKey和getValue可以分别获取key和value
Set<Entry> entrySet
该方法会将Map中每一组键值对(Entry实例)存入一个Set集合返回
*/
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
for (Map.Entry<Integer, String> e : entrySet) {
Integer integer = e.getKey();
String string = e.getValue();
System.out.println("key" + "\t" + integer);
System.out.println("value" + "\t" + string);
}
/*
3.遍历所有的value
Collection values()
该方法将当前map中所有的value存入到一个集合中返回
*/
Collection<String> collection = map.values();
System.out.println("?"+collection);
for (String s : collection) {
System.out.println(s);
}
}
}
/*
当一个实例作为HashMap的key时,它的equals方法和hashcode方法的重写直接影响着
散列表(HashMap)的查询性能。
当重写equals方法时,应当连同重写hashcode方法
这两个方法重写应当遵循:
1.一致性:当两个对象equals比较为true时,hashcode方法返回的数字必须相等,反过来虽然不是必须的,
但也应当遵循,否则HashMap中形成的链表会影响查询性能.
所以两个对象的hashcode值相同,equals比较也应当为true
2.稳定性:hashcode方法多次调用后返回的数字应当相同,除非参与equals比较的属性值发生了变化
*/
/*
初始容量:默认16
加载因子:0.75
性能优化:加载因子较小时,散列查找性能高,但也浪费了空间。
0.75是性能和空间相对平衡结果
当空间不够会扩容,存储位置会变化,叫rehash
object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,
当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,
导致混淆,因此,就也需要重写hashcode()
*/
public class Map4 {
private int x;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Map4)) return false;
Map4 map4 = (Map4) o;
return x == map4.x &&
y == map4.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}