Map集合

import java.util.Map;
import java.util.HashMap;
public class a{
  public static void main(String[] args){
    Map map = new HashMap();
    map.put("书本1",100);
    map.put("书本2",200);
    map.put("书本3",300);
    //新value覆盖原有value,返回原value
    System.out.println(map.put("书本1",120));
    //输出map
    System.out.println(map); 
    System.out.println("是否包含值为'书本2'的key:" + map.containsKey("书本2"));
    System.out.println("是否包含值为 200 的value:" + map.containsValue(200));
    for(Object key : map.keySet()){
      //
      System.out.println(key + "-->" + map.get(key));
    }
    //根据key来删除key-value对
    map.remove("书本2");
    System.out.println(map);
  }
}

Java8为Map新增的方法

import java.util.Map;
import java.util.HashMap;
public class a{
  public static void main(String[] args){
    Map map = new HashMap();
    map.put("书本1",100);
    map.put("书本2",200);
    map.put("书本3",300);
    //替换书本2的value为250,若map中没有对应key,不会添加key-value对
    map.replace("书本2",250);
    //若找不到key,则新增一个key-value对;若找到的key的value为空,则直接用传入的value覆盖;若找到的key不为空,则根据原value、新value计算一个新的结果。
    map.merge("书本2",240,(oldVal,param) -> (Integer)oldVal + (Integer)param);
    //若key对应的value为空,则使用参数二计算的结果覆盖value。若Map不包含key,可能会添加一组key-value对。
    map.computeIfAbsent("书本4",(key) -> ((String)key).length());
    //若key对应的value存在时,计算结果若不为null,则覆盖原value。计算结果若为null,则删除原key-value对。
    map.computeIfPresent("书本1",(key,value) -> (Integer)value * (Integer)value);
    System.out.println(map);
  }
}

Java8改进的HashMap和Hashtable实现类

类似于HashSet、HashMap、Hashtable判断两个key相等的标准是:两个key通过equals()方法比较返回true,两个key的hashCode值也相等。判断两个value相等的标准更简单:只要两个对象通过equals()方法返回true即可。

LinkedHashMap实现类

LinkedHashMap也使用双向链表来维护key-value(只考虑key的次序),该链表负责维护Map的迭代顺序,迭代顺序与key-value对的插入顺序一致。

import java.util.LinkedHashMap;
public class a{
  public static void main(String[] args){
    LinkedHashMap map = new LinkedHashMap();
    map.put("书本1",100);
    map.put("书本2",200);
    map.put("书本3",300);
    map.forEach((key,value) -> System.out.println(key + "-->" + value));
  }
}

LinkedHashMap可以记住key-value的添加顺序。

使用Properties读写属性文件

Properties类是Hashtable类的子类。相当于一个key、value都是String类型的Map。

import java.util.Properties;
import java.io.FileOutputStream;
import java.io.FileInputStream;
public class a{
  public static void main(String[] args)throws Exception{
    Properties props = new Properties();
    props.setProperty("username","czd");
    props.setProperty("password","123456");
    //将Properties中的key-value对保存到a.ini文件中
    props.store(new FileOutputStream("a.ini"),"comment line");
    
    Properties props2 = new Properties();
    props2.setProperty("gender","male");
    //将a.ini文件中的key-value对追加到props2中
    props2.load(new FileInputStream("a.ini"));
    System.out.println(props2);
  }
}

a.ini文件内容:

#comment line
#Wed Jun 13 21:01:43 CST 2018
password=123456
username=czd

SortedMap接口和TreeMap实现类

TreeMap有两种排序方式:

1.自然排序:TreeMap的所有key必须实现Comparable接口,而且所有key都应该是同一个类的对象,否则可能导致ClassCastException异常

2.定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。采用定制排序时不要求Map的key实现Comparable接口。

TreeMap中判断两个key相等的标准是:两个key通过compareTo()方法返回0。

如果使用自定义类作为TreeMap的key,需重写equals()方法和compareTo()方法。当equals()方法返回true时,它们通过compareTo()方法比较应该返回0。

再次强调:Set和Map的关系十分密切,Java源码就是先实现了HashMap、TreeMap等集合,然后通过包装一个所有value都为null的Map集合实现了Set集合。

 

import java.util.TreeMap;
class R implements Comparable{
  int count;
  public R(int count){
    this.count = count;
  }
  public String toString(){
    return "R[count:" + count + "]";
  }
  public boolean equals(Object obj){
    if(this == obj){
      return true;
    }
    if(obj != null && obj.getClass() == R.class){
      R r = (R)obj;
      return r.count == this.count;
    }
    return false;
  }
  public int compareTo(Object obj){
    R r = (R)obj;
    return count > r.count ? 1 : count < r.count ? -1 : 0;
  }
}
public class a{
  public static void main(String[] args){
    TreeMap tm = new TreeMap();
    tm.put(new R(0),"书本1");
    tm.put(new R(-5),"书本2");
    tm.put(new R(5),"书本3");
    System.out.println(tm);
    //返回该TreeMap的第一个entry对象
    System.out.println(tm.firstEntry());
    //返回该TreeMap的最后一个key值
    System.out.println(tm.lastKey());
    //返回该TreeMap的比new R(4)大的最小key值
    System.out.println(tm.higherKey(new R(-1)));
    //返回该TreeMap的比new R(1)小的最大key-value对
    System.out.println(tm.lowerEntry(new R(1)));
    //返回该TreeMap的子TreeMap
    System.out.println(tm.subMap(new R(0),new R(6)));
  }
}

 

WeakHashMap实现类

WeakHashMap与HashMap的用法基本相似。区别是:HashMap的key保留了对实际对象的强引用,而WeakHashMap只保留了对实际对象弱引用。这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收(System.gc(),System.runFinalization()),WeakHashMap也可能自动删除这些key所对应的key-value对。

IdentityHashMap实现类

 

IdentityHashMap与HashMap的用法基本相似。但它在处理两个key相等时比较独特:在IdentityHashMap中,当且仅当两个key严格相等(key1==key2)时,IdentityHashMap才认为两个key相等。对于普通的HashMap,只要key1和key2通过equals()方法比较返回true,且它们的hashCode值相等即可。

EnumMap实现类

EnumMap中的所有key都必须是单个枚举类的枚举值

 

import java.util.EnumMap;
enum Season{
  SPRING,SUMMER,FALL,WINTER
}
public class a{
  public static void main(String[] args){
    EnumMap enumMap = new EnumMap(Season.class);
    enumMap.put(Season.SUMMER,"夏日炎炎");
    enumMap.put(Season.SPRING,"穿暖花开");
    System.out.println(enumMap);
  }
}