Java容器---Map基础
1.Map API
(1)Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。
java.util Interface Map<K,V> 参数类型:K--Map的Key(键) V--Map的与Key对应的Value(值) 实现的子类:AbstractMap , Attributes , EnumMap , HashMap, Hashtable , LinkedHashMap , |
(2)Map.Entry,是Map的嵌套类,它用来描述Map中的键/值对。
static interface Map.Entry<K,V> :Map条目(键值对)。
(3)覆盖Object 的两个方法,以正确比较 Map 对象的等价性
(4)常用方法
void clear() 从该地图中删除所有的映射(可选操作)。 |
boolean containsValue(Object value) 如果此地图将一个或多个键映射到指定的值,则返回 true。 |
boolean isEmpty() 如果此地图不包含键值映射,则返回 true 。 |
int size() 返回此地图中键值映射的数量。 |
Collection<V> values() 返回此地图中包含的值的Collection视图。 |
default void replaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。 |
2.HashMap
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
直接子类:LinkedHashMap , PrinterStateReasons
HashMap基于哈希表(“拉链法”实现哈希表,可参见数据结构-哈希表)实现的Map接口,。 此实现提供了所有可选的Map操作,并允许null的值和null键。
HashMap类大致相当于Hashtable ,除了它是不同步的,如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,那么它必须在外部进行同步。。
这个类不能保证Map的顺序; 特别是,它不能保证订单在一段时间内保持不变。
构造方法 |
HashMap() :构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。(见下面注意) |
HashMap(int initialCapacity) :构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。 |
HashMap(int initialCapacity, float loadFactor) :构造一个空的 HashMap具有指定的初始容量和负载因子。 |
HashMap(Map<? extends K,? extends V> m): 构造一个新的 HashMap与指定的相同的映射 Map 。 |
注意:
HashMap的一个实例有两个影响其性能的参数: 初始容量和负载因子 。 容量是哈希表中的桶数,初始容量只是创建哈希表 (数据结构-哈希表)时的容量。 负载因子是在容量自动增加之前允许哈希表得到满足的度量。 当在散列表中的条目的数量超过了负载因数和容量的乘积,哈希表被重新散列 (即,内部数据结构被重建),使得哈希表具有桶的大约两倍。
作为一般规则,默认负载因子(.75)提供了时间和空间成本之间的良好折中。 更高的值会降低空间开销,但会增加查找成本(反映在 HashMap类的大部分操作中,包括get和put )。 在设置其初始容量时,应考虑Map中预期的条目数及其负载因子,以便最小化重新组播操作的数量。 如果初始容量大于最大条目数除以负载因子,则不会发生重新排列操作。
常用方法和Map相同
3.Hashtable
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map <K,V>, Cloneable ,Serializable
已知直接子类: Properties , UIDefaults
该类实现了一个哈希表(“拉链法”实现哈希表),它将键映射到值。 任何非null
对象都可以用作键值或值。
为了从散列表成功存储和检索对象,用作键的对象必须实现hashCode
方法和equals
方法。
构造方法 |
Hashtable() :构造一个新的,空的散列表,默认初始容量(11)和负载因子(0.75)。 |
Hashtable(int initialCapacity) :构造一个新的,空的哈希表,具有指定的初始容量和默认负载因子(0.75)。 |
Hashtable(int initialCapacity, float loadFactor): 构造一个新的,空的哈希表,具有指定的初始容量和指定的负载因子。 |
Hashtable(Map<? extends K,? extends V> t) :构造一个与给定地图相同的映射的新哈希表。 |
Hashtable 与HashMap比较
相同点:
- 都实现了Map、Cloneable、Serializable接口
- 底层都是基于“拉链法”实现哈希表
不同的:
- 线程安全不同:HashMap单线程安全,HashTable多线程安全
- NULL的处理不同:HashMap的Key和Value可以为Null,HashTable的Key和Value非 Null
- 遍历:HashMap支持Iterator;HashTable支持Iterator和Enumeration
- 类型不同:HashMap基于AbstractMap,HashTable基于Dictionary
4.TreeMap
public class TreeMap<K,V>
extends AbstractMap <K,V>
implements NavigableMap<K,V>, Cloneable , Serializable
TreeMap基于红黑树实现
NavigableMap。 红黑树是一种自平衡的二叉树,即左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。红黑树虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。(点击查看关于数据结构---红黑树的文章) |
![]() |
构造方法 |
TreeMap():使用其键的自然排序构造一个新的空树状图。 |
TreeMap(Comparator<? super K> comparator):构造一个新的,空的树图,按照给定的比较器排序。 |
TreeMap(Map<? extends K,? extends V> m) :造一个新的树状图,其中包含与给定地图相同的映射,根据其键的 自然顺序进行排序 。 |
TreeMap(SortedMap<K,? extends V> m) :造一个包含相同映射并使用与指定排序映射相同顺序的新树映射。 |
5.Properties
public class Properties
extends Hashtable <Object ,Object>
直接子类:ProviderProperties类表示一组持久的属性。看参见Java I/O---Properties类(持久化键值对)因为Properties从继承Hashtable时, put种putAll方法可应用于Properties对象。 强烈不鼓励使用它们,因为它们允许调用者插入其键或值不是Strings , 应该使用setProperty方法。这个类是线程安全的:多个线程可以共享一个Properties对象,而不需要外部同步。
构造方法 |
Properties() :创建一个没有默认值的空属性列表。 |
Properties(Properties defaults):创建具有指定默认值的空属性列表。 |
常用方法 |
String getProperty(String key) :使用此属性列表中指定的键搜索属性。 |
String getProperty(String key, String defaultValue) :使用此属性列表中指定的键搜索属性。 |
void list(PrintStream out /PrintWriter out) : 将此属性列表打印到指定的输出流 |
void load(InputStream inStream/Reader reader) : 从输入字节流读取属性列表(键和元素对)。 |
void loadFromXML(InputStream in) :将指定输入流中的XML文档表示的所有属性加载到此属性表中。 |
Enumeration<?> propertyNames() :返回此属性列表中所有键的枚举,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
Object setProperty(String key, String value) :取代 Hashtable方法 put 。 |
void storeToXML(OutputStream os, String comment, String encoding) :使用指定的编码发出表示此表中包含的所有属性的XML文档。 |
Set<String> stringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
6.Map的方法演示
public class MapDemo { /** * @param args */ public static void main(String[] args) { Map<Integer,String> map = new HashMap<Integer,String>(); methodDemo(map); /* * 需求:Map集合中存储学号,姓名。 */ } public static void methodDemo(Map<Integer,String> map){ //1,存储键值对。如果键相同,会出现值覆盖。 System.out.println(map.put(3, "xiaoqiang")); System.out.println(map.put(3, "erhu")); map.put(7, "wangcai"); map.put(2, "daniu"); // System.out.println(map.remove(7)); System.out.println(map.get(7)); System.out.println(map); } }
public class MapTest { /** * @param args */ public static void main(String[] args) { /* * 什么时候使用map集合呢? * 当需求中出现映射关系时,应该最先想到map集合。 * */ String cnWeek = getCnWeek(3); System.out.println(cnWeek); String enWeek = getEnWeek("星期八"); System.out.println(enWeek); } //根据中文星期,获取对应的英文星期。 //中文与英文相对应,可以建立表,没有有序的编号,只能通过map集合。 public static String getEnWeek(String cnWeek){ //创建一个表。 Map<String,String> map = new HashMap<String,String>(); map.put("星期一","Monday"); map.put("星期二","Tuesday"); map.put("星期三","Wednesday"); map.put("星期四","Thursday"); map.put("星期五","Friday"); map.put("星期六","Saturday"); map.put("星期日","Sunday"); return map.get(cnWeek); } /** * 根据用户的指定的数据获取对应的星期。 */ public static String getCnWeek(int num){ if(num<=0 || num>7){ throw new NoWeekException(num+",没有对应的星期"); } String[] cnWeeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"}; return cnWeeks[num]; } }
public class Employee implements Comparable<Employee> { private String name; private int age; public Employee() { super(); } public Employee(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; } @Override public String toString() { return "Emplooye [name=" + name + ", age=" + age + "]"; } @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; Employee other = (Employee) 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; } @Override public int compareTo(Employee o) { int temp = this.age - o.age; return temp==0? this.name.compareTo(o.name):temp; } } /////////////////////////////////////////////////////////////////////////////////////////// public class HashMapTest { /** * @param args */ public static void main(String[] args) { /* * 1, 将员工和归属存储到HashMap集合中并取出。 同姓名同年龄视为同一个学生。 */ Map<Employee,String> map = new HashMap<Employee,String>();//如果改成LinkedHashMap可以实现有序。 map.put(new Employee("xiaozhang",24),"北京"); map.put(new Employee("laoli",34),"上海"); map.put(new Employee("mingming",26),"南京"); map.put(new Employee("xili",30),"广州"); map.put(new Employee("laoli",34),"铁岭"); Set<Employee> keySet = map.keySet(); for(Employee employee : keySet){ String value = map.get(employee); System.out.println(employee.getName()+":"+employee.getAge()+"...."+value); } // for(Employee employee : map.keySet()){ // // } } }
public class TreeMapTest { /** * @param args */ public static void main(String[] args) { /* * 2, 按照学生的年龄进行升序排序并取出。 按照学生的姓名进行升序排序并取出。 */ // 自定义比较器。 Comparator<Employee> comparator = new Comparator<Employee>() { @Override public int compare(Employee o1, Employee o2) { int temp = o1.getName().compareTo(o2.getName()); return temp == 0 ? o1.getAge() - o2.getAge() : temp; } }; Map<Employee, String> map = new TreeMap<Employee, String>(comparator); map.put(new Employee("xiaozhang", 24), "北京"); map.put(new Employee("laoli", 34), "上海"); map.put(new Employee("mingming", 26), "南京"); map.put(new Employee("xili", 30), "广州"); map.put(new Employee("laoli", 34), "铁岭"); // entrySet Set<Map.Entry<Employee, String>> entrySet = map.entrySet(); for (Map.Entry<Employee, String> me : entrySet) { Employee key = me.getKey(); String value = me.getValue(); System.out.println(key.getName() + "::" + key.getAge() + "....." + value); } } }
2018-01-07
内容主要来自API
Java容器---Map基础的更多相关文章
- Java容器Map接口
Map接口容器存放的是key-value对,由于Map是按key索引的,因此 key 是不可重复的,但 value 允许重复. 下面简单介绍一下Map接口的实现,包括HashMap,LinkedHas ...
- java容器 Map Set List
容器:在java中,如果有一个类专门用来存放其他类的对象,这个类就叫做容器,或者叫集合,集合就是将若干性质相同或者相近的类的对象组合在一起而形成一个整体. boolean add(Object obj ...
- java容器-Map
Map:基本思想是映射表(维护键-值对),HashMap,TreeMap,LinkedHashMap,ConcurrentHashMap等都是基于Map接口实现的map容器,他们特性不同,表现在效率, ...
- Java容器——Map接口
1.定义 Map用于保存存在映射关系<key, value>的数据.其中key值不能重复(使用equals()方法比较),value值可以重复. 2.常用实现类 HashMap:和Hash ...
- 【公开课】【阿里在线技术峰会】魏鹏:基于Java容器的多应用部署技术实践
对于公开课,可能目前用不上这些,但是往往能在以后想解决方案的时候帮助到我.以下是阿里对公开课的整理 摘要: 在首届阿里巴巴在线峰会上,阿里巴巴中间件技术部专家魏鹏为大家带来了题为<基于Java容 ...
- 【Java心得总结七】Java容器下——Map
我将容器类库自己平时编程及看书的感受总结成了三篇博文,前两篇分别是:[Java心得总结五]Java容器上——容器初探和[Java心得总结六]Java容器中——Collection,第一篇从宏观整体的角 ...
- 工作随笔—Java容器基础知识分享(持有对象)
1. 概述 通常,程序总是运行时才知道的根据某些条件去创建新对象.在此之前,不会知道所需对象的数量,甚至不知道确切的类型,为解决这个普遍的编程问题:需要在任意时刻和任意位置创建任意数量的对象,所以,就 ...
- java容器基础
总结一下学过的java容器知识. 一.java容器框架 由于之前学习的java容器类比较混乱,先简单的整理一下java集合框架. 首先,像这种图,网上到处都是,因为这个也算比较准确吧,我也懒得自己画了 ...
- Java 容器(list, set, map)
java容器类库的简化图: (虚线框表示接口, 实线框表示普通的类, 空心箭头表示特定的类实现了接口, 实心箭头表示某个类可以生成箭头所指的类对象) 继承Collection的主要有Set 和 Lis ...
随机推荐
- SQL Server学习之路(二):主键和外键
0.目录 1.定义 1.1 什么是主键和外键 1.2 主键和外键的作用 1.3 主键.外键和索引的区别 2.主键(primary key) 2.1 通过SSMS设置主键 2.2 通过SQL语句设置主键 ...
- python中csv文件的读取问题
在python读取csv格式的文件时,使用csv.reader读取文件对象,出现了line contains NULL byte的错误,如下: reader = csv.reader(open(fil ...
- NOIP2012junior—P1—质因数分解
NOIP2012junior-P1-质因数分解 时间: 1000ms / 空间: 131072KB [背景] NOIP2012[描述] 已知正整数n 是两个不同的质数的乘积,试求出较大的那个质数. [ ...
- java学习笔记之System类
System类常用总结 System类概述 java.lang.System类,系统属性信息工具类 常用静态方法: 1. public static long currentTimeMillis() ...
- cronlog分割tomcat catalina.out日志
Tomcat 下日志文件 catalina.out 过大,几百兆或几个G,进而造成再也无法写入更多的日志内容,至使 Tomcat 无法处理请求,所以依靠cronlog来分割: 具体步骤如下: 1.安装 ...
- java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
1.错误描写叙述 java.sql.SQLException: Can not issue data manipulation statements with executeQuery(). at c ...
- 【Java入门提高篇】Day10 Java代理——静态代理
今天要介绍的是一个Java中一个很重要的概念--代理. 什么是代理?联系生活想想看,代理似乎并不陌生,最形象的代表便是经纪人,明星一般都有经纪人,经纪人作为中间人,负责代理明星的相关事宜,比如说,有人 ...
- 控制反转-Ioc之Unity
本篇幅主要介绍控制反转的一些概念,和如何使用Unity实现Ioc.在介绍的时候,会尽量结合代码来讲解一些概念. 1.什么是DI? DI即控制反转,是将对具体实现类的依赖转变为对接口的依赖,这样在编程中 ...
- Java实现的电脑已连接WiFi热点的导入导出小工具
很多时候我们电脑连接了很多无线WiFi,只要连接过一次,电脑就会记下该热点的密码,方便我们下一次连接.但是问题来了,一旦我们重装系统,之前连接过的WiFi就丢失了,想要连接就得再输入密码,为了 解决这 ...
- Web服务器、应用服务器、Web容器、反向代理服务器区别与联系
作者: 帅虫哥 出处:www.cnblogs.com/vipyoumay/p/7455431.html(点击尾部阅读原文前往) 我们知道,不同肤色的人外貌差别很大,而双胞胎的辨识很难.有意思的是Web ...