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 ...
随机推荐
- Selenium中如何使用xpath更快定位
在学习Selenium路上,踩了也不少坑,这是我最近才发现的一个新写法,好吧,"才发现"又说明我做其他事了.对的,我现在还在加班! 开车~~~ 例子:知乎网 标签:Python3. ...
- 大白话Vue源码系列(02):编译器初探
阅读目录 编译器代码藏在哪 Vue.prototype.$mount 构建 AST 的一般过程 Vue 构建的 AST 题接上文,上回书说到,Vue 的编译器模块相对独立且简单,那咱们就从这块入手,先 ...
- ettercap的中间人欺骗
环境准备:kali系统 因为kali系统自带ettercap,比较方便, 不需要安装 ifcofing命令查看当前网关 ,当前的IP是: 172.16.42.1 查找局域网所有主机 通过netdisc ...
- Android笔记二十四.Android基于回调的事件处理机制
假设说事件监听机制是一种托付式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源和事件监听器是统一的,或者说事件监听器全然消失了,当用户在GUI控件上激发某个事件时,控 ...
- JAVA入门[16]-form表单,上传文件
一.如何传递参数 使用 @RequestParam 可以传递查询参数.例如:http://localhost:8092/category/detail?id=1 @RequestMapping(&qu ...
- spring mvc对静态资源的访问
如果我们的项目使用的是springmvc,在web.xml中会有一段这的配置. <servlet> <servlet-name>springMvc</servlet-na ...
- sqlser 2005 对称加密,非对称加密笔记
一:对称加密 原始明文---密钥---加密数据---密钥---原始明文 速度快,通过算法将明文混淆,占用系统资源少 二:非对称加密 加密解密速度慢,较高的系统资源占用 三:混合数据加密 加密过程:随 ...
- 通过gitbub桌面工具同步
1.先创建目录,和选择路径 2.commit -> sync 3. cd ~/.ssh 查看公钥 在github 添加公钥. 4. 克隆文件git clone git@github.con:cu ...
- MFC学习之CWinApp类
CWinApp是一个基类,你通过它来继承Windows应用程序对象.应用程序对象为你提供了初始化应用程序(以及它的每一个实例 和运行应用程序所需的成员函数.它实现主事件循环并把事件分发给MFC中其他类 ...
- Eclipse 插件安装、升级和卸载的方法
Eclipse 的插件可以装在内部,也可以装在外部,装在内部的方法很简单:把插件的features和plugins目录copy到eclipse的安装目录即可. eclipse和其插件升级比较频繁,用过 ...