知乎专栏 |
Map ├Hashtable ├HashMap └WeakHashMap Map接口 请注意,Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。 Hashtable类 Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。 添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。 Hashtable通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。 使用Hashtable的简单示例如下,将1,2,3放到Hashtable中,他们的key分别是”one”,”two”,”three”: Hashtable numbers = new Hashtable(); numbers.put(“one”, new Integer(1)); numbers.put(“two”, new Integer(2)); numbers.put(“three”, new Integer(3)); 要取出一个数,比如2,用相应的key: Integer n = (Integer)numbers.get(“two”); System.out.println(“two = ” + n); 由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方 法。hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相 同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如 果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希 表的操作。 如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。 Hashtable是同步的。 HashMap类 HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap 的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。 WeakHashMap类 WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。
Map<String, Object> data = new HashMap<String, Object>() { { put("name", "neo"); } };
private static final Map<String, String> point; static { point = new HashMap<String, String>(); point.put("CN", "China"); point.put("HK", "Hongkong"); point.put("TW", "Taiwan"); };
public final static Map<String, String> hostMap = new HashMap<String, String>() { { put("redis", "127.0.0.1"); put("solr", "127.0.0.1"); } }; public final static Map map = new HashMap() {{ put("key1", "value1"); put("key2", "value2"); }};
Map<String, String> emptyMap = Collections.emptyMap(); public static Map<String, String> createSingletonMap() { return Collections.singletonMap("username1", "password1"); }
数组方式
Map<String, String> map = Stream.of(new String[][] { { "Hello", "World" }, { "Neo", "Chen" }, }).collect(Collectors.toMap(data -> data[0], data -> data[1]));
对象方式
Map<String, Integer> map = Stream.of(new Object[][] { { "Neo", 1 }, { "Netkiller", 2 }, }).collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1]));
使用 Collectors.collectingAndThen()初始化不可变的Map
Map<String, String> map = Stream.of(new String[][] { { "Hello", "World" }, { "John", "Doe" }, }).collect(Collectors.collectingAndThen( Collectors.toMap(data -> data[0], data -> data[1]), Collections::<String, String> unmodifiableMap));
使用 Entry 接口的SimpleEntry 实现 :
Map<String, Integer> map = Stream.of( new AbstractMap.SimpleEntry<>("idea", 1), new AbstractMap.SimpleEntry<>("mobile", 2)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
使用SimpleImmutableEntry 实现:
Map<String, Integer> map = Stream.of( new AbstractMap.SimpleImmutableEntry<>("idea", 1), new AbstractMap.SimpleImmutableEntry<>("mobile", 2)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map<String, String> emptyMap = Map.of(); Map<String, String> singletonMap = Map.of("key1", "value"); Map<String, String> map = Map.of("key1","value1", "key2", "value2");
Map<String, String> map = Map.ofEntries( new AbstractMap.SimpleEntry<String, String>("name", "Neo"), new AbstractMap.SimpleEntry<String, String>("city", "Shenzhen"), new AbstractMap.SimpleEntry<String, String>("zip", "518000"), new AbstractMap.SimpleEntry<String, String>("home", "https://www.netkiller.cn") );
Map<String, Integer> session = new HashMap<String, Integer>(); session.put("A",1); ... ... session.put("Z",26) for (Map.Entry<String, Integer> entry : session.entrySet()) { System.out.println(String.format("%s:%d", entry.getKey(), entry.getValue())); } Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); }
Map<Integer, Integer> map = new HashMap<Integer, Integer>(); //遍历map中的键 for (Integer key : map.keySet()) { System.out.println("Key = " + key); }
Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (Integer value : map.values()) { System.out.println("Value = " + value); }
Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (Integer key : map.keySet()) { Integer value = map.get(key); System.out.println("Key = " + key + ", Value = " + value); }
Map<Integer, Integer> map = new HashMap<Integer, Integer>(); Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); while (entries.hasNext()) { Map.Entry<Integer, Integer> entry = entries.next(); System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); } Map map = new HashMap(); Iterator entries = map.entrySet().iterator(); while (entries.hasNext()) { Map.Entry entry = (Map.Entry) entries.next(); Integer key = (Integer)entry.getKey(); Integer value = (Integer)entry.getValue(); System.out.println("Key = " + key + ", Value = " + value); }
import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; public class TestLinkedHashMap { public static void main(String args[]) { System.out.println("*** LinkedHashMap ***"); Map<Integer,String> map = new LinkedHashMap<Integer,String>(); map.put(6, "apple"); map.put(3, "banana"); map.put(2,"pear"); for (Iterator it = map.keySet().iterator();it.hasNext();) { Object key = it.next(); System.out.println( key+"="+ map.get(key)); } System.out.println("*** HashMap ***"); Map<Integer,String> map1 = new HashMap<Integer,String>(); map1.put(6, "apple"); map1.put(3, "banana"); map1.put(2,"pear"); for (Iterator it = map1.keySet().iterator();it.hasNext();) { Object key = it.next(); System.out.println( key+"="+ map1.get(key)); } } }
Map<Integer, String> map = new HashMap<Integer, String>(){{ put(1, "127.0.0.1"); put(2, "192.168.0.1"); put(3, "172.16.0.1"); }}; for (Integer key : map.keySet()) { System.out.println("key= "+ key + ", value= " + map.get(key)); }
Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }
Map<String, Integer> items = new HashMap<>(); items.put("A", 10); items.put("B", 20); items.put("C", 30); items.put("D", 40); items.put("E", 50); items.put("F", 60); items.forEach((k,v)->System.out.println("key : " + k + "; value : " + v)); //output key : A value : 10 key : B value : 20 key : C value : 30 key : D value : 40 key : E value : 50 key : F value : 60 items.forEach((k,v)->{ System.out.println("key : " + k + " value : " + v); });
Map<Integer, String> map = new HashMap<Integer, String>(){{ put(1, "127.0.0.1"); put(2, "192.168.0.1"); put(3, "172.16.0.1"); }}; Integer[] keys = map.keySet().toArray(new Integer[0]); Random random = new Random(); Integer randomKey = keys[random.nextInt(keys.length)]; String randomValue = map.get(randomKey); System.out.println(randomValue);